2012-08-06 25 views
3

我有一个托管对象与成员类的一对多关系。当我为成员添加观察者时,它就起作用了。当一个新成员添加到关系中时,将使用新对象调用observeValueForKeyPath,并且更改字典包含新成员对象。然而,observeValueForKeyPath将被第二次触发,所有值为nil并且改变字典new =“NULL”。第二个触发器是什么?我设置了一个断点,但不知道谁是触发器。KVO为一对多,但NSNull对象传入observeValueForKeyPath

@interface FooObject : NSManagedObject {} 
@property (nonatomic, strong) NSString *fooId; 
@property (nonatomic, strong) NSSet* members; 
@end 

@implementation FooObject 
@dynamic fooId; 
@dynamic members; 

- (NSMutableSet*)membersSet { 
    [self willAccessValueForKey:@"members"]; 

    NSMutableSet *result = (NSMutableSet*)[self mutableSetValueForKey:@"members"]; 

    [self didAccessValueForKey:@"members"]; 
    return result; 
} 

- (void)registerObservers { 
    [self addObserver:self 
      forKeyPath:@"members" 
       options:NSKeyValueObservingOptionNew 
       context:nil]; 
} 

- (void)unregisterObservers { 
    @try{ 
     [self removeObserver:self forKeyPath:@"members"]; 
    }@catch(id anException){ 
     //do nothing, obviously it wasn't attached because an exception was thrown 
    } 
} 

- (void)observeValueForKeyPath:(NSString *)keyPath 
         ofObject:(id)object 
         change:(NSDictionary *)change 
         context:(void *)context 
    id valueNewSet = [change objectForKey:NSKeyValueChangeNewKey]; 
    if (![valueNewSet isKindOfClass:[NSSet class]]) { 
      // not a NSSet, it contains <null> value 
      NSLog(@"%@", change); 
      NSLog(@"%@", object); 
    } 
    if ([[change objectForKey:NSKeyValueChangeKindKey] intValue] == NSKeyValueChangeInsertion) { 
      // insert change is valid, process the changes 
    } 

} 
@end 

日志输出:

{ 
    kind = 1; 
    new = "<null>"; 
} 

<FooObject: 0xfa9cc60> (entity: FooObject; id: 0xfa9be00 <x-coredata://39DB31FD-6795-4FDE-B700-819AB22E5170/SHInterest/p6> ; data: { 
    fooId = nil; 
    members = nil; 
}) 

EDIT 1 我在NSLog的设置断点(@ “%@”,变更); 这是堆栈跟踪,但对进行此调用的图形没有什么帮助。

主 - > UIApplicationMain - > NSKeyValueNotifyObserver - > observeValueForKeyPath:ofObject变化:上下文

EDIT 2 也许这仍然是一个错误? http://www.cocoabuilder.com/archive/cocoa/182567-kvo-observevalueforkeypath-not-reflecting-changes.html

+0

当你停在断点处时,它应该会显示堆栈跟踪。这应该包含一些关于为什么被调用的线索。 – 2012-08-06 22:49:13

+0

是的,但堆栈跟踪根本没有帮助。我更新了跟踪。 – angelokh 2012-08-06 23:21:08

+0

这里的复杂因素是你并没有观察到一个单一的值,而是一个关系。从文档:“如果观察到的属性是一对多关系,则NSKeyValueChangeKindKey条目还会分别指示关系中的对象是插入,移除还是替换,分别返回NSKeyValueChangeInsertion,NSKeyValueChangeRemoval或NSKeyValueChangeReplacement。” – 2012-08-08 15:11:58

回答

0

我遇到了这里的“隐性”的分配(和国际志愿者组织观察员因此通知)仅作为重新分配MO的一部分显然出现了同样的问题:我挽救一个孩子MOC,然后松开,那么iOS版发布其MO。我假设它在释放相关MO(其中应用了删除规则级联)的过程中临时将一对多关系设置为NSNull

因此,旁边要改变插入和删除的种类,我的KVO观察者现在也接受NSKeyValueChangeSetting并断言change[NSKeyValueChangeNewKey] == NSNull.null。称它为一个实用的解决方案。