Cocoa 如何绑定到NSArrayController';s排列的对象
我想以编程方式将自定义类(Cocoa 如何绑定到NSArrayController';s排列的对象,cocoa,binding,key-value-observing,nsarraycontroller,kvc,Cocoa,Binding,Key Value Observing,Nsarraycontroller,Kvc,我想以编程方式将自定义类(MyClass)数组绑定到数组控制器(NSArrayController),并将其内容绑定到另一个数组(modelArray)MyClass显示数组的内容,如NSTableView 我的问题是:如何以调用可变数组的方法(即方法)的方式创建此绑定 -(void) insertObject:(id)object inContentAtIndex:(NSUInteger)index -(void) removeObjectFromContent:(id) object (1
MyClass
)数组绑定到数组控制器(NSArrayController
),并将其内容绑定到另一个数组(modelArray
)MyClass
显示数组的内容,如NSTableView
我的问题是:如何以调用可变数组的方法(即方法)的方式创建此绑定
-(void) insertObject:(id)object inContentAtIndex:(NSUInteger)index
-(void) removeObjectFromContent:(id) object
(1) 如果以这种方式绑定,则会调用上述方法,但控制器的内容不再绑定到modelArray
(显然)
(2) 如果以这些方式绑定,则只调用setContent:
和content
方法,而不调用可变方法。我还尝试删除这些方法(setContent:
和content
),但它只会引发一个异常setValue:forundeindekey:
[myClassInstance bind:@"content" toObject:myArrayController withKeyPath:@"arrangedObjects" options:nil];
或
我不相信在绑定到数组控制器时,每次添加一行时都会重新设置整个表的数组,我希望使用相同的绑定。您遇到的问题与如何通过键值编码处理数组值有关。KVC没有特定类型的概念,因此当您通过KVC访问数组值时,它无法知道返回的数组是可变的。它必须假设最坏的情况(即数组是不可变的)。它通常处理这个问题的方式是使用一个代理对象,这个代理对象的行为类似于NSMutableArray,但在幕后它使用假定的不可变数组,创建一个可变副本,变异副本,然后使用setter将整个过程推回。(这就是您所看到的行为——整个数组正在被替换,而不是在适当的位置进行变异。) 控制此功能的方法是
-(NSMutableArray*)mutableArrayValueForKey:(NSString*)键
。在这个方法中可能会发生很多事情,我将在下面粘贴这个方法的标题注释,以给出完整的故事,但长话短说,如果您希望NSArrayController在适当的位置修改您的可变数组,最简单的方法是将此重写添加到提供modelArray
属性的类:
- (NSMutableArray *)mutableArrayValueForKey:(NSString *)key
{
if ([@"modelArray" isEqual: key])
{
// We know this is mutable, even if KVC doesn't!
return self.modelArray;
}
return [super mutableArrayValueForKey:key];
}
更长远的说法是,KVC在试图找出如何处理集合突变时,会寻找一系列的东西。它们在NSKeyValueCoding.h
中有详细的解释。以下是mutableArrayValueForKey:
的注释
给定一个标识有序对多关系的键,返回
一个可变数组,提供对相关数据的读写访问
物体。添加到可变数组的对象将与
从可变数组中移除的对象将成为
无关的
此方法的默认实现识别相同的简单
访问器方法和数组访问器方法为-valueForKey:,和
遵循相同的直接实例变量访问策略,但始终
返回可变集合代理对象,而不是不可变集合代理对象
valueForKey:将返回的集合。它还:
-removeObjectFromAtIndex:
(对应于NSMutableArray类定义的两个最基本的方法),以及
(在Mac OS 10.4中引入)也-插入:a索引:
和
-移除索引:
(对应于-[NSMutableArray insertObjects:atIndexes:
和-[NSMutableArray
RemoveObjectSatiIndex://code>)。如果至少有一种插入方法和
每个发送到的NSMutableArray消息都至少找到一种删除方法
集合代理对象将导致
-insertObject:inandex:
,-removeObjectFromAtIndex:
,-insert:atindex:
,以及-removeatindex:
发送到-mutableArrayValueForKey:
原始接收方的消息。如果
类还实现了一个可选方法,该方法的名称为
匹配模式-replaceObjectionIndex:withObject:
或
(在Mac OS 10.4中引入)-replaceAntidexes:with:
方法将在适当时使用,以获得最佳性能
-设置:
。如果在每个NSMutableArray中找到这样的方法
发送到集合代理对象的消息将导致
-set:
消息被发送到-mutableArrayValueForKey:
的原始接收方+accessInstanceVariablesDirectly
方法返回YES,在接收方的类中搜索名称与
按该顺序排列模式\uuu
或
。如果这样的实例变量
则每个NSMutableArray消息都会发送到集合代理
对象将转发到实例变量的值,该值
因此,通常必须是NSMutableArray的实例或
NSMutableArray的子类-setValue:forundeindekey:
正在发送给的原始接收方的消息
-mutableArrayValueForKey:
。-setValue:forUndefinedKey:
的默认实现会引发一个NSUndefinedKeyException,但您可以在应用程序中重写它[myClassInstance bind:@"content" toObject:myArrayController withKeyPath:@"content" options:nil];
- (NSMutableArray *)mutableArrayValueForKey:(NSString *)key
{
if ([@"modelArray" isEqual: key])
{
// We know this is mutable, even if KVC doesn't!
return self.modelArray;
}
return [super mutableArrayValueForKey:key];
}