Blockstrap
In my current project I had a simple little task. I had to keep a queue of audio alerts that would be dealt with on a first-in, first-out basis. Each item had two properties — an identifier and a timestamp (which could be absent, indicating that it had no yet played). The wrinkle on all this is that we didn't want to repeat the same audio alert (in some cases) within a certain amount of time. So, conceptually:
[AlertManager playAudioAlert:(id)alertId];
- If there's no queue, create one. (It's an NSMutableDictionary.)
- Goes through queue and throws out anything that was played within the last kAlertNoRepeatSeconds.
- If any remaining alert matches the new one, then bail.
- Otherwise, add the new alert to the end of the queue. (It's an NSMutableDictionary with one property.)
- If no alert is currently playing [Alert Manager playNextAlert].
- If there's an audioPlayer instanced
- Check if audioPlayer is playing. If it is, bail.
- If not, find the first unplayed item (i.e. one with no timestamp property) in the queue.
- If found, play it and tack on a timestamp. (Add a property to the dictionary.)
- Tell the audioPlayer that the current thing is its delegate.
- [AlertManager playNextAlert];
AudioAlertManager = { queue: [], playAudioAlert: function(alertId){ ... }, playNextAlert: function( ... ) }
Note that the third function is obviated because we can simply pass playNextAlert directly to the alertPlayer as the thing it calls when it finishes playing. So no messing up your nice class with a new protocol, and no sudden complication if we need to use two of these things. (Consider the case of a UIView that contains two UITableViews.)
So how can we make coding this stuff in Objective-C as much like doing it in JavaScript as possible and makes sense? Imagine also that we'd actually like the items in our queue to behave like proper (strongly typed) objects (because while this case is trivial, it could easily grow into a non-trivial and hard to maintain case).
The fundamental problem here is that Cocoa was written before blocks, so you have a lot of classes that idiomatically want to be passed either:
- a receiver object and a selector
- or a delegate object which implements an interface
This leads us onto the next obvious use case. Defining a UITableView. But that's getting ahead of ourselves.