NSNotificationCenter Block-based Observer

Back in iOS 4, a nifty block-based observer method was added to NSNotificationCenter:

- (id)addObserverForName:(NSString *)name object:(id)obj queue:(NSOperationQueue *)queue usingBlock:(void (^)(NSNotification *))block;

Super convenient, right? I love using blocks to pass simple callbacks to controllers instead of creating a delegate protocol. There is a catch with this method, and it’s not terribly obvious unless you’re looking closely. The method returns (id) – according to Apple’s documentation the return object is “An opaque object to act as the observer”.  What does this mean?

Typically when you register your class instance as an observer, you pair it with a removeObserver somewhere else usually in dealloc.  The thing is, removing self will NOT remove block-based observers! The opaque object that the method returned needs to be retained somewhere so that removeObserver can be called with that object. This is especially important if you’re calling self within the block to eliminate a retain cycle/memory leak.

Read more about the method and it’s usage in Apple’s documentation.

iOS Basics: nil vs NULL vs NSNull

Yes, there are three ways to represent a null value in Objective-C.

NULL = Absence of a value with C-style pointers
nil = Absence of value with Objective-C object variables
NSNull = A nil boxed as an object for storage in a collection

If you try adding nil to a NSDictionary or NSArray, you will find out it doesn’t perform as expected.  If you absolutely need to store a null value in a collection, you can use NSNull to represent the lack of a value.  For example:

NSNull nullValue = [NSNull null];
[anArray addObject:nullValue];

Note, however, that since NSNull represents the lack of a value, there is no way to retrieve that value from the collection. In order to determine if there is no value for a particular key or index, you must compare against NSNull.

id value = [anArray objectAtIndex:3];
if (value == [NSNull null]) {
  // Do something for a null
}