Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cocoa/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Cocoa 如何绑定到NSArrayController';s排列的对象_Cocoa_Binding_Key Value Observing_Nsarraycontroller_Kvc - Fatal编程技术网

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的子类
  • 否则(找不到数组变异方法、简单访问器方法或实例变量集),返回可变集合 还是代理对象。每个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];
    }