I feel much the same way, that is although I think Grand Central Dispatch is awesome, I simply haven't been able to justify spending much time with it, because it usually turns out that my own threading needs so far have been far more modest than what GCD provides. In fact, I find that an approach that's even more constrained than the one based on NSOperationQueue that Brent describes has been working really well in a number of projects.
Instead of queueing up operations and letting them unwind however, I just spawn a single I/O thread (at most a few) and then have that perform the I/O deterministically. This is paired with a downloader that uses the NSURL loading system to download any number of requests in parallel.
This loads 3 types of objects: first the thumbnails, then article content, then images associated with the articles. The sequencing is both deliberate (thumbs first, article images cannot be loaded before the article content is present) and simply expressed in the code by the well-known means of just writing the actions one after the other, rather than having those dependencies expressed in call-backs, completion blocks or NSOperation subclasses.
- (void)downloadNewsContent { id pool=[NSAutoreleasePool new]; [[self downloader] downloadRequests:[self thumbnailRequests]]; [[self downloader] downloadRequests:[self contentRequests]]; [[self downloader] downloadOnlyRequests:[self imageRequests]]; [pool release]; }
So work is done semi-sequentially in the background, while coordination is done on the main thread, with liberal use of performSelectorOnMainThread. Of course, I make that a little simpler with a couple of HOMs that dispatch messages to threads:
- async runs the message on a new thread, I use it for long-running, intrinsically self contained work. It is equivalent to performSelectorInBackground: except for being able to take an arbitrary message.
- asyncOnMainThread and syncOnMainThread are the equivalents of performSelectorOnMainThread, with the waitUntilDone flag set to YES or NO
- afterDelay: sends he message after the specified delay
Brent sums it up quite well in his post:
-(void)loadSections { [[self asyncOnMainThread] showSyncing]; [[[self sections] do] downloadNewsContent]; [[self asyncOnMainThread] showDoneSyncing]; } ... -(IBAction)syncButtonClicked { [[self async] loadSections]; }
Here’s the thing about code: the better it is, the more it looks and reads like a children’s book.Yep.
No comments:
Post a Comment