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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/google-apps-script/5.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/github/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 观察可可中多对多关系的关键价值_Cocoa_Key Value Observing_Key Value Coding - Fatal编程技术网

Cocoa 观察可可中多对多关系的关键价值

Cocoa 观察可可中多对多关系的关键价值,cocoa,key-value-observing,key-value-coding,Cocoa,Key Value Observing,Key Value Coding,我正在尝试让键值为NSMutableArray工作。下面是MyObservee的.h文件,即观察到的类: @interface MyObservee : NSObject { @private int someValue; @private NSMutableArray *someArray; } @property (readwrite,assign) int someValue; - (NSMutableArray *)someArray; @end MyObserver

我正在尝试让键值为NSMutableArray工作。下面是MyObservee的.h文件,即观察到的类:

@interface MyObservee : NSObject {
    @private int someValue;
    @private NSMutableArray *someArray;
}

@property (readwrite,assign) int someValue;
- (NSMutableArray *)someArray;
@end
MyObserver类实现observeValueForKeyPath:ofObject:change:context:。下面是我添加观察者的方式:

MyObservee *moe = [[MyObservee alloc] init];
MyObserver *mobs = [[MyObserver alloc] init];

[moe addObserver:mobs 
      forKeyPath:@"someArray" 
         options:(NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld) 
         context:NULL];

[moe.someArray addObject:@"hi there"];

为什么addObject:消息不会作为对someArray键路径的更改而触发?我有一种感觉,这里有一些我不完全理解的东西。

不幸的是,NSArray类是与note KVO兼容的。它们与KVC兼容,但您不能像在这里尝试的那样直接观察它们。获得此功能的最简单方法是使用NSArrayController。NSArray控制器与KVO兼容,在添加或删除项目时会向您发出警报。在您的示例中,如果您实际更改了阵列本身,将通知您的观察者。例如,如果您这样做:

[moe setSomeArray:[NSMutableArray array]];

这可能根本不是您想要的:)顺便说一句,NSDictionary实际上是兼容KVO的,所以如果您愿意,您可以使用它。或者,您可以编写NSMutableArray的包装器子类,该子类只创建一个真正的可变数组作为其备份存储,但只将所有消息转发给它,
addObject
removeObject
除外,您可以覆盖它们以触发通知。

您需要实现中定义的索引数组访问器。然后必须使用这些访问器访问阵列,KVO触发将起作用。您还可以调用并使用该数组来addObject:等等,它将依次调用访问器方法,KVO触发也将发生。还有用于NSSET的集合访问器,请参阅和

例如:

@interface MyClass : NSObject
{
    NSMutableArray *_orders;
}

@property(retain) NSMutableArray *orders;

- (NSUInteger)countOfOrders;
- (id)objectInOrdersAtIndex:(NSUInteger)index;
- (void)insertObject:(id)obj inOrdersAtIndex:(NSUInteger)index;
- (void)removeObjectFromOrdersAtIndex:(NSUInteger)index;
- (void)replaceObjectInOrdersAtIndex:(NSUInteger)index withObject:(id)obj;


@end

为什么要将私有数组传递给另一个对象?当您让其他对象处理它时,它就不是那么隐私了

正如s-bug所说,您应该实现访问器并使用
mutableArrayValueForKey:
来修改属性。我补充说,您根本不应该公开这个私有数组——您的
someArray
方法应该返回数组的不可变副本


此外,我提请大家注意Jason Coco对s-bug答案的评论。为了解释他的意思,您可能应该使用
NSArrayController
作为
myObservee
myobserve
之间的额外分离步骤。这是一个很好的建议,如果你没有具体的理由直接观察酒店,你应该接受它。(其中一个好处是,您可以使用绑定将视图连接到新的阵列控制器。)

或。。。您可以使用NSArrayController;-)Jason Coco:是的,通常应该使用NSArrayController,但这并不能解决如何改变底层模型和获取KVO通知的问题。