I am currently observing a notification throughout the life of an object in a category. However, I am swizzling the dealloc method to have a spot to remove the observation. This feels bad and I am uncomfortable with it, additionally I am running into problems.
Does anyone have any ideas how I can stop observing the notification just before the object will be deallocated within a category?
The best way to run code at the deallocation of an object for which you can't override dealloc
is by using associated objects.
The object that you associate to will release its strongly-held associated objects when it deallocates. As long as that is the only owner, the associated object's dealloc
will then be called. Using a class you control for the associated object, that's your entry point.
I've got a demonstration of using this trick to deregister for KVO in a GitHub repo https://github.com/woolsweater/UIViewController-WSSDataBindings
The controller associates a helper object to itself:
- (void)WSSBind:(NSString *)bindingName
toObject:(id)target
withKeyPath:(NSString *)path
{
WSSBinding * binding = [WSSBinding bindingWithBoundName:bindingName
onObject:self
toKeyPath:path
ofObject:target];
// Attach the binding to both target and controller, but only make it
// owned by the target. This provides automatic deregistration when the
// target is destroyed, and allows the controller to unbind at will.
// Disregard the target and bound path for the key to allow mirroring
// Cocoa's unbind: method; this is simplest for the controller.
NSUInteger key = [self WSSAssociateKeyForBinding:bindingName];
objc_setAssociatedObject(target, (void *)key, binding,
OBJC_ASSOCIATION_RETAIN_NONATOMIC);
objc_setAssociatedObject(self, (void *)key, binding,
OBJC_ASSOCIATION_ASSIGN);
}
And the WSSBinding
class implements dealloc
to remove the observer that's been set up elsewhere. You can do the same for your NSNotification
registration.