Send Notification When a Property is Changed Using KVO

13,717

Solution 1

Try this:

MyClass *var = [MyClass new];
[var addObserver:self forKeyPath:@"myName" options:NSKeyValueChangeOldKey context:nil];

and implement

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{

}

this method will be called anytime when myName property changes

Solution 2

In - (void)setMyName:(NSString *)name do this instead

[self willChangeValueForKey:@"myName"];
_myName = name;
[self didChangeValueForKey:@"myName"];

//this generates the KVO's

And where you want to listen (the viewController), there in viewDidLoad add this line:

[w addObserver:self forKeyPath:@"myName" options:NSKeyValueObservingOptionNew context:nil];

//By doing this, you register the viewController for listening to KVO.

and also implement this method:

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
    if ([[change objectForKey:NSKeyValueChangeNewKey] isEqual:[NSNull null]]) {
        return;
    } else {
        //read the change dictionary, and have fun :)
    }
}

//this method is invoked, whenever the property's value is changed.

Solution 3

To do this without the customer setter, just synthesize the property setter. This will create all the supporting calls to willChangeValueForKey / didChangeValueForKey.

@synthesize myName;

Then set property values with dot-syntax:

self.myName = @"Inigo Montoya"

Then the observers will receive the KVO notification automatically.

(You will need to remove the observer before you release the observed object.)

Share:
13,717
Midhun MP
Author by

Midhun MP

Coding is my passion. Working as a mobile app developer and specifically focused on ios + android + flutter + node.js I ❤️ to learn new technologies.

Updated on June 08, 2022

Comments

  • Midhun MP
    Midhun MP almost 2 years

    I had a property named myName in my class, like:

    @property (nonatomic, strong) NSString *myName;
    

    I need to send a notification when the myName property's value is changed.

    Now I'm doing something like:

    - (void)setMyName:(NSString *)name
    {
      _myName = name;
      [[NSNotificationCenter defaultCenter] postNotificationName:CHANGE_NOTIFICATION object:nil];
    }
    

    I know there is something like Key-Value Observing in iOS. But I don't know how to implement it, I read the entire document, but couldn't get a good understanding.

    Please help me to understand how to implement the same without using custom setter.

  • NicTesla
    NicTesla about 9 years
    Hi, i was wondering if the KVO solution is better then the other implementation solution. Can anyone explain that?
  • Chris
    Chris about 9 years
    This answer is much better than the accepted answer, which doesn't show how to implement KVO, only how to listen for KVO notifs that are already implemented
  • brainray
    brainray over 7 years
    @NiCTesla: that is exactly my thought. AFAIR KVO should only be used if no other mechanism can do the job (NSOperation is an example here). I also think Notifications result in more understandable, less error prone code.