Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
Evil KVO context hack using macros + C99 compound literal syntax.
// Building upon:
// Defines a unique KVO context by taking the address of a 2-element string array.
// Using __FILE__ ensures the address is unique across source files, even with link time optimization.
#define DDDefineContext(_X_) static void * _X_ = &(const char *[] ) {#_X_, __FILE__}
// Example Definition
// Example Usage. No need for &MyFooContext to make it unique.
- (void)startObserving
[_ivar addObserver:self forKeyPath:@"foo" options:0 context:MyFooContext];
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
// In a debugger, use `p *(char **)context` to dump the context
if (context == MyFooContext) {
// foo changed
} else {
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
- (void)stopObserving
[_ivar removeObserver:self forKeyPath:@"foo" context:MyFooContext];

I feel like I should point you at @mikeash's incredibly clever use of C:

static const void *MyFooContext = &MyFooContext;

MyFooContext is initialized at load time with a pointer to itself.


ddribin commented Mar 14, 2013

Yeah, but I really like being able to print out the context in OVFKP while debugging and get something useful.

0xced commented Mar 14, 2013

It looks like you missed a mention ;-)

@ddribin Re You can correlate the context address with a particular context variable: (gdb) info symbol context

Or with lldb (given that you defined MyFooContext as Kyle described):

(lldb) image lookup -a `context`
      Address: MyApp[0x00026258] (MyApp.__DATA.__data + 4)
      Summary: MyFooContext

ddribin commented Mar 14, 2013

Oh… nice! Yeah, I didn’t know about the syntax. That does work well. Less hacky, too. Thanks!

Because gist comment markdown sucks, I didn't realize you folks were referring to the shell-like backtick syntax. I was worried vararg macros were somehow involved…

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