Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save Akhrameev/0ad905d652ae152a9419 to your computer and use it in GitHub Desktop.
Save Akhrameev/0ad905d652ae152a9419 to your computer and use it in GitHub Desktop.
removeObserver swizzling added + SWIZZLE_NSNOTIFICATIONCENTER + separate .h and .m files
#import <Foundation/Foundation.h>
@interface NSNotificationCenter (AllObservers)
- (NSSet *) my_observersForNotificationName:(NSString *)notificationName;
@end
#import "NSNotificationCenter+AllObservers.h"
#import <Foundation/Foundation.h>
#import <objc/runtime.h>
@implementation NSNotificationCenter (AllObservers)
const static void *namesKey = &namesKey;
+ (void) load
{
#if (SWIZZLE_NSNOTIFICATIONCENTER)
method_exchangeImplementations(class_getInstanceMethod(self, @selector(addObserver:selector:name:object:)),
class_getInstanceMethod(self, @selector(my_addObserver:selector:name:object:)));
method_exchangeImplementations(class_getInstanceMethod(self, @selector(removeObserver:)),
class_getInstanceMethod(self, @selector(my_removeObserver:)));
method_exchangeImplementations(class_getInstanceMethod(self, @selector(removeObserver:name:object:)),
class_getInstanceMethod(self, @selector(my_removeObserver:name:object:)));
#endif
}
- (void)my_removeObserver:(id)observer name:(NSString *)aName object:(id)anObject {
NSDictionary *names = [self names];
[self removeObserver:observer fromNames:names withName:aName];
[self my_removeObserver:observer name:aName object:anObject];
}
- (void)removeObserver:(id)observer fromNames:(NSDictionary *)names withName:(NSString *)aName {
NSMutableSet *observers = [names valueForKey:aName];
if ([observers containsObject:observer]) {
[observers removeObject:observer];
}
}
- (void)my_removeObserver:(id)observer {
if (observer) {
NSDictionary *names = [self names];
for (NSString *aName in names) {
[self removeObserver:observer fromNames:names withName:aName];
}
}
[self my_removeObserver:observer];
}
- (void) my_addObserver:(id)notificationObserver selector:(SEL)notificationSelector name:(NSString *)notificationName object:(id)notificationSender
{
[self my_addObserver:notificationObserver selector:notificationSelector name:notificationName object:notificationSender];
if (!notificationObserver || !notificationName)
return;
NSMutableDictionary *names = [self names];
NSMutableSet *observers = [names objectForKey:notificationName];
if (!observers)
{
observers = [NSMutableSet setWithObject:notificationObserver];
[names setObject:observers forKey:notificationName];
}
else
{
[observers addObject:notificationObserver];
}
}
- (NSMutableDictionary *)names {
NSMutableDictionary *names = objc_getAssociatedObject(self, namesKey);
if (!names)
{
names = [NSMutableDictionary dictionary];
objc_setAssociatedObject(self, namesKey, names, OBJC_ASSOCIATION_RETAIN);
}
return names;
}
- (NSSet *) my_observersForNotificationName:(NSString *)notificationName
{
NSMutableDictionary *names = objc_getAssociatedObject(self, namesKey);
return [names objectForKey:notificationName] ?: [NSSet set];
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment