【问题标题】:How to bind to NSArrayController's arranged objects如何绑定到 NSArrayController 的排列对象
【发布时间】:2012-08-14 04:07:24
【问题描述】:

我想以编程方式将自定义类 (MyClass) 数组绑定到数组控制器 (NSArrayController),并将其内容绑定到另一个数组 (modelArray)。 MyClass 显示数组的内容,如NSTableView

我的问题是:如何以调用可变数组的方法的方式创建此绑定,即方法

-(void) insertObject:(id)object inContentAtIndex:(NSUInteger)index
-(void) removeObjectFromContent:(id) object

(1)如果我这样绑定,上面的方法都被调用了,但是控制器的内容不再绑定到modelArray(很明显)

[myArrayController bind:@"contentArray" toObject:myClassInstance withKeyPath:@"content" options:nil];

(2) 如果我以这些方式绑定,则只调用 setContent:content 方法,而不调用可变方法。我还尝试删除这些方法(setContent:content),但它只会引发异常 setValue:forUndefinedKey:

[myClassInstance bind:@"content" toObject:myArrayController withKeyPath:@"arrangedObjects" options:nil];

[myClassInstance bind:@"content" toObject:myArrayController withKeyPath:@"content" options:nil];

我不相信每次在绑定到数组控制器时添加一行时都会重新设置整个表的数组,我希望有相同类型的绑定。

【问题讨论】:

    标签: cocoa binding key-value-observing nsarraycontroller kvc


    【解决方案1】:

    您遇到的问题与键值编码如何处理数组值有关。 KVC 没有特定类型的概念,所以当你通过 KVC 访问一个数组值时,它无法知道返回的数组是可变的。它必须假设最坏的情况(即数组是不可变的)。它通常处理这个问题的方式是使用一个代理对象,acts 就像一个 NSMutableArray,但在幕后它需要你假定的不可变数组,制作一个可变副本,改变副本,然后推送整个回到使用二传手的事情。 (这是您看到的行为——整个数组被替换而不是被原地变异。)

    控制此功能的方法是- (NSMutableArray *)mutableArrayValueForKey:(NSString *)key。该方法可能会发生很多事情,我将在下面粘贴此方法的标题 cmets 以提供完整的故事,但长话短说,如果您希望 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: 的 cmets。

    给定一个标识有序对多关系的键,返回 一个可变数组,提供对相关的读写访问 对象。添加到可变数组的对象将与 接收者,并且从可变数组中删除的对象将变为 无关的。

    此方法的默认实现识别相同的简单 访问器方法和数组访问器方法为 -valueForKey:'s,以及 遵循相同的直接实例变量访问策略,但始终 返回一个可变集合代理对象而不是不可变的 -valueForKey: 将返回的集合。它还:

    1. 在接收者的类中搜索名称与-insertObject:in<Key>AtIndex: 和模式匹配的方法 -removeObjectFrom<Key>AtIndex:(对应NSMutableArray类定义的两个最原始的方法),和 (在 Mac OS 10.4 中引入)还有 -insert<Key>:atIndexes:-remove<Key>AtIndexes:(对应-[NSMutableArray insertObjects:atIndexes:]-[NSMutableArray removeObjectsAtIndexes:])。如果至少有一种插入方法并且在 每个发送到的 NSMutableArray 消息都至少找到一种删除方法 集合代理对象将导致某些组合 -insertObject:in<Key>AtIndex:-removeObjectFrom<Key>AtIndex:-insert<Key>:atIndexes:-remove<Key>AtIndexes: 消息被发送到 -mutableArrayValueForKey: 的原始接收者。如果 接收者的类还实现了一个可选方法,其名称 匹配模式 -replaceObjectIn<Key>AtIndex:withObject: 或 (在 Mac OS 10.4 中引入)-replace<Key>AtIndexes:with<Key>: 那 将在适当的时候使用方法以获得最佳性能。
    2. 否则(未找到数组变异方法集),在接收器的类中搜索名称匹配的访问器方法 模式-set<Key>:。如果找到这样的方法,每个 NSMutableArray 发送到集合代理对象的消息将导致 -set<Key>: 消息正在发送给-mutableArrayValueForKey: 的原始接收者。
    3. 否则(未找到数组变异方法集或简单访问器方法),如果接收者的类' +accessInstanceVariablesDirectly 方法返回 YES,在接收者的类中搜索名称与 模式_<key><key>,按此顺序。如果这样的实例变量 找到后,将每条 NSMutableArray 消息发送到集合代理 对象将被转发到实例变量的值,这 因此通常必须是 NSMutableArray 的实例或 NSMutableArray 的子类。
    4. 否则(未找到数组变异方法、简单访问器方法或实例变量的集合),返回可变集合 无论如何代理对象。每个 NSMutableArray 消息发送到 集合代理对象将产生一个-setValue:forUndefinedKey: 消息被发送到原始接收者 -mutableArrayValueForKey:-setValue:forUndefinedKey: 的默认实现会引发 NSUndefinedKeyException,但您可以在应用程序中覆盖它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-09-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多