mikeash/MAZeroingWeakRef

Removing KVO observer causes crash

Closed this issue · 2 comments

Since, in case of a observed KVO object, MAZeroingWeakRef just replaces the KVOClass methods (release, dealloc, classForCoder) and, according my tests, KVO resets the original object class when the last observer is removed, the replaced methods are lost.

This snippet should demonstrates the issue;

NSObject *obj = [[NSObject alloc] init];
[obj addObserver:self forKeyPath:@"description" options:NSKeyValueObservingOptionNew context:nil];
MAZeroingWeakRef *weakRef = [MAZeroingWeakRef refWithTarget:obj];
[obj removeObserver:self forKeyPath:@"description"];
[obj release];
NSLog(@"weakRef %@", weakRef.target);

KVO is a persistent source of trouble for this project, sadly. I'm not entirely sure how this might be fixed. Is there a method that could be hooked to find out when KVO de-swizzles the object and fix things up at that point?

Thinking about it, the method to hook was just removeObserver:forKeyPath:. You'll get a lot of false positives that way, but it doesn't matter, since EnsureCustomSubclass is smart enough not to do anything unless it's necessary anyway.