在我的应用中,我有Restaurant
课程,您可以在下面看到。我想附上一个KVOController
。但我没有运气。当我用下面的代码附上它时,它会崩溃。
FBKVOController *KVOController = [FBKVOController controllerWithObserver:self];
self.KVOController = KVOController;
[self.KVOController observe:self keyPath:@"[Restaurant current].name.asString" options:NSKeyValueObservingOptionInitial|NSKeyValueObservingOptionNew block:^(id observer, id object, NSDictionary *change) {
DDLogDebug(@"Restaurant changed");
}];
将KVO添加到这样的类中的最佳方法是什么?
@implementation Restaurant
static Restaurant *current = nil;
+ (Restaurant *)current {
@synchronized(self) {
if (current == nil) {
current = [[Restaurant alloc] initWithId:0];
}
}
return current;
}
- (id)initWithId:(NSInteger)number {
self = [super init];
if (self)
{
...
}
return self;
}
@end
答案 0 :(得分:0)
问题不在于@synchronized
。您的代码存在以下几个问题:
+[Restaurant current]
指向不同的餐馆实例)。或者是由current
的更改或name
的更改引发的任何类型的名称更改?
observe:[Restaurant class]
或observe:[Restaurant instance]
,要求observe:self
,除非您在Restaurant
内进行设置类实现,在这种情况下[self class]
可以替代[Restaurant class]
)。+[Restaurant current]
的更改,也适用于-[Restaurant name]
的更改,具体取决于您希望能够观察到的内容。[Restaurant current].name.asString
不是有效的密钥路径。有效的密钥路径可能只包含属性名称(ASCII,以小写字母开头,没有空格)和用于分隔它们的点(有关详细信息,请参阅Key-value coding)。一旦你告诉KVOController observe:[Restaurant class]
,关键路径的剩余部分就是current.name.asString
。name
是什么?你真的需要将它转换成一个字符串来观察吗?如果您打算观察名称更改,则观察current.name
可能就足够了。您最终可能会遇到以下两种选择之一:
FBKVOController *kvoController = [FBKVOController controllerWithObserver:self];
[kvoController observe:[Restaurant class] keyPath:@"current.name" ...];`
// or
[kvoController observe:[Restaurant current] keyPath:@"name" ...];`
同样,对于任何可观察的变化,它们必须是KVO-compliant。