Skip to content

Instantly share code, notes, and snippets.

@andrewsardone
Created September 14, 2012 17:24
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save andrewsardone/3723354 to your computer and use it in GitHub Desktop.
Save andrewsardone/3723354 to your computer and use it in GitHub Desktop.
NSKeyValueObserving's use of a context pointer for identifying interested observations

The NSKeyValueObserving addition to NSObject adds an observe message that takes an identifying context pointer – don't use NULL in its place.

Your superclass may observe the same key path for the same object. You need to pass along its observations, and only take actions on yours. The context pointer distinguishes which observations are yours.

static void *kContext = &kContext;

//

// alternatively, you could just use self as the context pointer
void *context = (__bridge void *) self;

[obj addObserver:self
forKeyPath:key
       options:0
         context:kContext]; // <-- context pointer

//

- (void)observeValueForKeyPath:(NSString *)keyPath
                      ofObject:(id)object
                        change:(NSDictionary *)change
                       context:(void *)context
{
    if (context == kContext)
        // do stuff
    else
        [super observeValueForKeyPath:keyPath
                             ofObject:object
                               change:change
                              context:context];
}

via Mike Ash's Defensive Programming in Cocoa talkPDF.

Alternatively, you could use self as the context pointer:

void *context = (__bridge void *) self;

[obj addObserver:self
      forKeyPath:key
         options:0
         context:context];

//

- (void)observeValueForKeyPath:(NSString *)keyPath
                      ofObject:(id)object
                        change:(NSDictionary *)change
                       context:(void *)context
{
    if (context != (__bridge void *)self) {
        [super observeValueForKeyPath:keyPath
                             ofObject:object
                               change:change
                              context:context];
        return;
    }

    // do stuff
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment