2017-02-26 20 views
1

在我的应用程序中,我有Restaurant类,你可以在下面看到。我想附上一个KVOController它。但我没有运气。当我用下面的代码附加它时,它会崩溃。如何将KVO添加到同步课程?

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

的问题不是@synchronized。您的代码有几个问题:

  • 您是否想观察当前餐厅的变化?或者当前餐厅的名称发生变化(没有+[Restaurant current]指向不同的餐厅实例)。或者任何形式的名称更改,无论是由current更改还是name更改引发?
    • 根据不同的答案,你要么要观察observe:[Restaurant class]observe:[Restaurant instance],但绝对不是observe:self(除非你设置此功能的Restaurant类里面执行,在这种情况下[self class][Restaurant class]替代) 。
    • 对于任何可观察的变化,您必须确保该类以KVO-compliant的方式实施。这取决于您希望能够观察到的变化,以便更改为+[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