键值观察 - 如何观察对象的所有属性?

Col*_*inE 16 objective-c key-value-observing

我很高兴使用Key Value Observing(KVO),以及如何注册接收财产变更通知:

[account addObserver:inspector
          forKeyPath:@"openingBalance"
             options:NSKeyValueObservingOptionNew
              context:NULL];
Run Code Online (Sandbox Code Playgroud)

但是,如果我想观察帐户对象的所有属性的更改,我该如何实现?我是否必须注册每个房产的通知?

Vla*_*mir 19

似乎没有内置函数来订阅对象的所有属性的更改.

如果您不关心哪个属性已更改并且可以更改您的类,则可以向其添加虚拟属性以观察其他属性(使用+ 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;
}
Run Code Online (Sandbox Code Playgroud)

现在,如果您观察到dummy属性,每次更改任何对象的属性时,您都会收到KVO通知.

此外,您可以获取对象中所有属性的列表,如在发布的代码中,并在循环中为每个属性订阅KVO通知(因此您不必硬编码属性值) - 这样您将获得更改的属性如果你需要它的名字.

  • 这似乎是间接的,但指出了正确的方向.class_copyPropertyList()和property_getname()足以在每个属性上添加观察,与最初要求的完全相同. (4认同)