Forked from 0xced/NSNotificationCenter+AllObservers.m
Last active
August 29, 2015 14:02
-
-
Save Akhrameev/0ad905d652ae152a9419 to your computer and use it in GitHub Desktop.
removeObserver swizzling added + SWIZZLE_NSNOTIFICATIONCENTER + separate .h and .m files
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import <Foundation/Foundation.h> | |
@interface NSNotificationCenter (AllObservers) | |
- (NSSet *) my_observersForNotificationName:(NSString *)notificationName; | |
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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