Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Key Value Observing - how to observe all the properties of an object?

I am happy with the use of Key Value Observing (KVO), and how to register to receive notifications of property change:

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

However, if I want to observe changes in all the properties of the account object, how can I achieve this? Do I have to register for notification for each and every property?

like image 925
ColinE Avatar asked Nov 21 '12 10:11

ColinE


People also ask

What is key-value observing?

Key-value observing is a Cocoa programming pattern you use to notify objects about changes to properties of other objects. It's useful for communicating changes between logically separated parts of your app—such as between models and views. You can only use key-value observing with classes that inherit from NSObject .

What is key-value Coding and key-value observing?

KVO and KVC or Key-Value Observing and Key-Value Coding are mechanisms originally built and provided by Objective-C that allows us to locate and interact with the underlying properties of a class that inherits NSObject at runtime.

How do you observe property in Swift?

Swift property observers For example, you could add a @WrappedDefault property to a view controller. To make use of the property observers within a centralized class like AppSettings , you would need to pass in a closure to execute in the observers or post a Notification — neither of which are ideal.

What is key-value coding?

About Key-Value Coding. Key-value coding is a mechanism enabled by the NSKeyValueCoding informal protocol that objects adopt to provide indirect access to their properties. When an object is key-value coding compliant, its properties are addressable via string parameters through a concise, uniform messaging interface.


1 Answers

It seems there's no built-in function to subscribe for changes in all properties of the objects.

If you don't care about which exactly property has changed and can change your class you can add dummy property to it to observe changes in other properties (using + keyPathsForValuesAffectingValueForKey or +keyPathsForValuesAffecting<Key> method):

// .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;
}

Now if you observe dummy property you'll get KVO notification each time any of object's properties is changed.

Also you can get list of all properties in the object as in the code posted and subscribe for KVO notifications for each of them in a loop (so you don't have to hard code property values) - this way you'll get changed property name if you need it.

like image 137
Vladimir Avatar answered Sep 18 '22 15:09

Vladimir