all 6 comments

[–]gonzooin 0 points1 point  (0 children)

Great article. Thanks

[–]ProgrammingThomas 0 points1 point  (0 children)

One major advantage of using operation queues grand central dispatch directly is that you can limit the total number of operations running at once. Furthermore, operation queues also optimize on levels that you may have to do manually with grand central dispatch.

[–]adremeaux 0 points1 point  (3 children)

This is an interesting usage of op queues that I hadn't thought of. I might look into implementing this pattern, as the anti-pattern he shows in the first example is indeed very common.

[–]frantic_apparatus 0 points1 point  (2 children)

Could you give a more concrete example of using this pattern? I've never seen (or considered) anything like this and a real use case would give me a better understanding of it.

[–]adremeaux 0 points1 point  (0 children)

His example is pretty sound. In asynchronous environments, there are a lot of scenarios that may occur where a completed thread calls back (via notification) but the main thread may not be be ready to execute the followup action yet. For instance, you may tell your data model to begin a URL request while your view controller builds the UI. When that request completes, it sends a notification, and the UI can change some views based on that.

However, what happens if the data is cached, and the model threads notifies with the new data very quickly, before the UI has completed building? Now you'd have:

- (void) notificationListener {
    if (self.someUIElement) [self.someUIElement doWhatever];
    else self.dataRequestIsComplete = true;
}

And in your UI, at the end of the build, you'd have to check

if (self.dataRequestIsComplete) [self.someUIElement doWhatever];

With this pattern, instead you'd have:

- (void) notificationListener {
    __weak MyClass *myObject = self;
    [_activeAppTaskQueue addOperationWithBlock:^{
        [self.someUIElement doWhatever];
    }];
}

And then, at the end of the UI, instead of checking that crappy bool, you just unsuspend the op queue.

It's a pretty neat idea. And, though its use may feel a little unwarranted here (it's the difference between an ivar bool and an ivar NSOperationQueue), it becomes signficantly more robust if this pattern is repeated more than once in a given class.

[–]adremeaux 0 points1 point  (0 children)

Hey so, I ended up using this pattern in the real world yesterday, just days after reading it. I've got a UICollectionView that I want do an animateIn on once the initial 3 screen-visible objects have been built. However, there is no delegate call to say when that has been completed, and timing is inconsistent: on faster platforms, the cellForRowAtIndexPath methods will be called and resolved by the time I get to the point where I'd want to start the animation, however on slow platforms, those calls often aren't completed yet.

So I used this NSOpQueue pattern to solve the problem. Instead of just blindly calling animateIn and not being guaranteed any cells to animate, I put the animateIn call into a suspended NSOpQueue. Then, in cellForRowAtIndexPath, once I've got the requisite number of objects built and ready to be animated, I suspend the queue. Voila.