Even Apple Leaves TODOs in Production Code

My credit card got charged today for my Apple Watch which wasn’t supposed to ship until June. I was so excited that I tweeted the shipping notification to sarcastically note the availability in June still.

Screen capture of the Preparing Shipment notification with a note of the watch being available in June

Copying that text into a tweet, I actually got:

Preparing for Shipment TODO: Pull info bubble content div up to the order list level (only need 1 per page) and refactor info bubbles into single conditional & span based on group status type OR alternatively, refactor to single info bubble per delivery group based on status shipped shipped Available to ship: June

So it appears that even Apple developers leave TODOs in production code. I don’t feel so bad now that I do it. 🙂

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.