Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Notification for property changes in NSObject

Is it possible to be notified for changes of all properties in an object? I would like to have a selector called whenever one of the properties in an NSObject is changed.

So far, I've only seen keyPathsForValuesAffectingValueForKey:, which isn't what I want, but it is persistent in showing up in my search results.

The specific objective that I currently have is to have a "FilterModel" that has properties for the specific filter characteristics. When any property is changed, I would like to update a UITableView with the newly filtered results.

like image 963
RileyE Avatar asked Jan 12 '23 19:01

RileyE


2 Answers

Depending on what you need one of these two options might be what you're looking for.

KVO Observing

KVO Observing provides a framework for automatically listening on property changes without requiring modifications of getters and setters. Simply have to add your listening object as an observer or your target object via:

addObserver:forKeyPath:options:context:

Then within your observer's implementation, implement:

observeValueForKeyPath:ofObject:change:context:

and check if the path a notification was caught for matches your desired property. For more on receiving KVO notifications see this. For more details and a better visualization of the concept of KVO Observing see the KVO Developer documentation.

Manual NSNotifications

If you want to fine tune which changes you're interested in, whenever you make a change to your object of interest through the setter post a notification via:

postNotificationName:object:userInfo:

This will allow you to precisely customize what changes you're interested in, rather than hope for the exact behavior you're looking for from something like keyPathsForValuesAffectingValueForKey:. You can then catch these notifications by listening for your named notifications in your relevant views via:

addObserver:selector:name:object:

You can read more about posting notifications on the NSNotificationCenter documentation.

like image 154
alexgophermix Avatar answered Jan 17 '23 20:01

alexgophermix


You might be able to do that by querying the properties list of an object using Objective-C runtime and registering your custom class as an observer to them.

#import <objc/runtime.h>


//id yourObject;

unsigned int count;
objc_property_t* properties = class_copyPropertyList([yourObject class], &count);
for (int i = 0; i < count; i++)
{
    const char* propertyName = property_getName(properties[i]);
    NSString *stringPropertyName = [NSString  stringWithCString:propertyName encoding:NSUTF8StringEncoding];
    [yourObject addObserver:self forKeyPath:stringPropertyName options:NSKeyValueObservingOptionNew context:nil];
}

Also, don't forget to remove your custom class from the observer list before deallocation. Whenever a property changes, the called method is:

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
like image 25
Antoine Lamy Avatar answered Jan 17 '23 21:01

Antoine Lamy