2012-11-21 193 views
16

我很高興與使用密鑰值觀察(志願),以及如何註冊以接收屬性更改的通知:關鍵值觀察 - 如何觀察對象的所有屬性?

[account addObserver:inspector 
      forKeyPath:@"openingBalance" 
      options:NSKeyValueObservingOptionNew 
       context:NULL]; 

但是,如果我想觀察的帳戶對象的所有屬性的變化,我怎麼能做到這一點?我是否需要爲每個物業註冊通知?

回答

17

似乎沒有內置函數來訂閱對象的所有屬性中的更改。

如果你不關心它究竟性能已經改變,可以改變你的類,你可以添加虛擬財產給它(使用+ keyPathsForValuesAffectingValueForKey+keyPathsForValuesAffecting<Key>法)觀察其他屬性的變化:

// .h. We don't care about the value of this property, it will be used only for KVO forwarding 
@property (nonatomic) int dummy; 

#import <objc/runtime.h> 
//.m 
+ (NSSet*) keyPathsForValuesAffectingDummy{ 

    NSMutableSet *result = [NSMutableSet set]; 

    unsigned int count; 
    objc_property_t *props = class_copyPropertyList([self class], &count); 

    for (int i = 0; i < count; ++i){ 
     const char *propName = property_getName(props[i]); 
     // Make sure "dummy" property does not affect itself 
     if (strcmp(propName, "dummy")) 
      [result addObject:[NSString stringWithUTF8String:propName]]; 
    } 

    free(props); 
    return result; 
} 

現在如果您觀察到dummy屬性,則每次更改任何對象的屬性時都會收到KVO通知。

此外,您可以獲取對象中的所有屬性列表,如發佈的代碼中所示,併爲循環中的每個人訂閱KVO通知(因此您不必硬編碼屬性值) - 這樣,如果你需要它會得到改變的屬性名稱。

+4

這似乎間接,但指出我在正確的方向。 class_copyPropertyList()和property_getname()足以在每個屬性上添加觀察值,完全按照最初的要求。 –

+0

那麼上面的代碼片段是否有更新呢? – fatuhoku

+0

另外,這是NSManagedObjects的工作嗎? – fatuhoku