iosobjective-ckey-value-observingselfaddobserver

addObserver on self


A pretty simple question, but I can't seem to find an answer. (Developing an iOS 5+ app).

In my AppDelegate, I have a property, let's call it @property (non atomic) BOOL aFlag;. I'd like my AppDelegate to be notified if the value changes. Here is what I tried (everything happens in the AppDelegate.m), which is the same as when I "link" two different objects with an observer :

-(BOOL)application:(UIApplication*)application 
       didFinishLaunchingWithOptions:(NSDictionary*)launchOptions {
    // Some stuff

    _aFlag = YES;
    [self addObserver:self 
           forKeyPath:@"aFlag" 
              options:(NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld) 
              context:nil];

    // Some other stuff
}


-(void)observeValueForKeyPath:(NSString*)keyPath 
                     ofObject:(id)object 
                       change:(NSDictionary*)change 
                      context:(void*)context {
    if ([keyPath isEqual:@"aFlag"]) {
        // Do something
    } else {
        // Do nothing
    }
}

But observeValueForKeyPath: is not called.

Where am I wrong ? Thanks.


Solution

  • You should implement your own setter. In that setter you know the poperty has changed.

    It's more optimised that way. Much better and less expensive then doing KVO on yourself.

    Your solution works, technically you can KVO yourself.

    But, imagine if you started using NSNotificationCenter for triggering methods in you class from inside your class? Can it be done? Yes. Should it be? Probably not. You may have a scenario where it's okay but not in a clean object oriented solution. You should be messaging self for this.

    Well it's the same here. Implement this:

    - (void)setAFlag:(BOOL)flag;
    

    For example:

    - (void)setAFlag:(BOOL)flag{
        BOOL valueChanged = NO;    
    
        if(_aFlag != flag){
           valueChanged = YES;
        }
        _aFlag = flag;
    
        if(valueChanged)
            [self doSomethingWithTheNewValueOfFlag];
    }