Skip to content

Instantly share code, notes, and snippets.

@nicklockwood
Last active April 27, 2016 16:18
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nicklockwood/7559729 to your computer and use it in GitHub Desktop.
Save nicklockwood/7559729 to your computer and use it in GitHub Desktop.
A proposal for an alternative NSNotificationCenter API that doesn't suck

Method

- (void)addObserver:(id)observer
            forName:(NSString *)name
             object:(id)object
              queue:(NSOperationQueue *)queue
         usingBlock:(void (^)(NSNotification *note, __weak id observer))block;

Usage

[[NSNotificationCenter defaultCenter] addObserver:self
                                          forName:NSSomeNotificationName
                                           object:nil
                                            queue:[NSOperationQueue mainQueue]
                                       usingBlock:^(NSNotification *note, __weak id observer) {
                                                      NSLog(@"self: %@", observer); //Look Ma, no leaks!
                                                  }];

Discussion

The observer object takes the place of the token in the current block-based API and works like the observer in the selector-based API. The block is retained by NSNotificationCenter only for as long as the observer exists. NSNotificationCenter does not retain the observer, so if all other references are deleted it will be destroyed, along with the block.

For convenience, a weak reference to the observer is passed as a second parameter to the block. The block can use this to refer to the observer (which would be 'self' in typical usage) to avoid doing the weakify dance.

There is no need to call removeObserver: in the observer's dealloc method, as the observer reference is cleaned up automatically when the observer is released. To remove the observer before it is released, you can use the existing removeObserver: APIs.

@jwilling
Copy link

@RuiAAPeres: Amended, however I still do want to keep mine prefixed.

@nicklockwood: Fixed (partially).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment