Reputation: 2269
I have an iPad app that uses a proprietary library object which registers for a "UIScreenDidConnectNotification". Occasionally this object is deallocated and reallocated behind the scenes. As it is in a library, I cannot ensure that it is properly removing this observer.
Is there a way for me to manually remove all/any observers for a specific notification (i.e. UIScreenDidConnectNotification) without having any access to the object that has registered. This would keep the application from sending the message to a deallocated object.
Update: Here is the easiest way to fix my problem. I wish I could do a better job, but life is too short. #import #import
@interface NSNotificationCenter (AllObservers)
@end
@implementation NSNotificationCenter (AllObservers)
// This function runs before main to swap in our special version of addObserver
+ (void) load
{
Method original, swizzled;
original = class_getInstanceMethod(self, @selector(addObserver:selector:name:object:));
swizzled = class_getInstanceMethod(self, @selector(swizzled_addObserver:selector:name:object:));
method_exchangeImplementations(original, swizzled);
// This function runs before main to swap in our special version of addObserver
+ (void) load
{
Method original, swizzled;
original = class_getInstanceMethod(self, @selector(addObserver:selector:name:object:));
swizzled = class_getInstanceMethod(self, @selector(swizzled_addObserver:selector:name:object:));
method_exchangeImplementations(original, swizzled);
}
/*
Use this function to remove any unwieldy behavior for adding observers
*/
- (void) swizzled_addObserver:(id)notificationObserver selector:(SEL)notificationSelector name:(NSString *)notificationName object:(id)notificationSender
{
NSString *notification = [[NSString alloc] initWithUTF8String: "UIScreenDidConnectNotification" ];
// It's a hack, but I just won't allow my app to add this type of notificiation
if([notificationName isEqualToString: notification])
{
printf("### screen notifcation added for an observer: %s\n", [notificationSender UTF8String] );
}
else
{
// Calls the original addObserver function
[self swizzled_addObserver:notificationObserver selector:notificationSelector name:notificationName object:notificationSender];
}
}
Upvotes: 0
Views: 172
Reputation: 3921
I agree with both of Caleb's points: it is not your responsibility to perform this task and there is nothing in the API to support it.
However... if you feel like hacking something in to perform this task for whatever reason, refer to this thread: How to retrieve all NSNotificationCenter observers?
The selected answer of that thread has a category for NSNotificationCenter
that allows you to retrieve all observers for a given notification name. Again, this is not recommended though.
Upvotes: 1
Reputation: 125017
As it is in a library, I cannot ensure that it is properly removing this observer.
If the object is created in a library, it's not your responsibility to remove the object. If the library is deallocating the object without removing it from the notification center, that's a clear bug in the library.
Is there a way for me to manually remove all/any observers for a specific notification... without having any access to the object that has registered.
There's nothing in the API for NSNotificationCenter that lets you do that. Just the opposite, in fact -- the methods that let you remove the observer all require a pointer to a specific object.
Upvotes: 2