2012-08-06 28 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。稱它爲一個實用的解決方案。