Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

@synchronized vs GCD dispatch_barrier_async

I've begun controlling queues for the first time and feel like I have a good handle on how to use them and kudos to Apple for making them quite straightforward to use.

What I encountered, however, is the challenge of multiple threads reading and writing to the same objects. In this question I got this fine answer, and it leaves me asking for some confirmation from everyone to make sure I understand the pros and cons of @synchronized vs GCD dispatch_barrier_async.

This is the way I see it:

 @synchronized

PRO: You can wrap any object in @synchronized as long as you have access/pointer to it, making it easy for shared data models to be safely handled from different objects in the program

PRO: Supported by iOS 4 (and maybe earlier)

 `dispatch_barrier_async` with custom DISPATCH_QUEUE_CONCURRENT

PRO: Is faster than @synchronized

CON: DISPATCH_QUEUE_CONCURRENT only available in iOS 5 (as discussed here), so not available for supporting iOS 4

CON: Not as easy to use when controlling read/write on an object from many other objects, since queues are most easily available only to the object that creates them (without some work to go around this limitation)

In summary, the best tool depends on the needs of the program, in consideration of the above.

If anyone has something to add or point out, I'd appreciate it.

like image 790
johnbakers Avatar asked Aug 12 '12 15:08

johnbakers


1 Answers

Well, a few things to point out:

1) When you use @synchronized, it pulls in the WHOLE exception framework for iOS (or OSX) for an app. I know of this on OSX and it has a performance impact there, cannot say for sure on iOS but would expect the same. That said, this is using a sledgehammer to drive in a nail - that capability was around way before other options were available. I personally avoid its use like the plague, and have ported other open source frameworks to use dispatch semaphores (I thank Mike Ash (again) for that!)

2) Your comment about "DISPATCH_QUEUE_CONCURRENT" is a red herring of sort - since iOS 4 the system has given you 3 concurrent queues so you really are pushing the envelope if you need to define your own. With dispatch, you have async and sync, serial and concurrent, groups that you can wait on, dispatch after. There is such a richness here how could you even think of 1). The more you use blocks the more you will use them!

EDIT: I used custom concurrent queues in my iOS 4.3 app, along with all the Mike Ash barrier techniques. The queue.h file shows it as available:

__OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_4_0)
DISPATCH_EXPORT DISPATCH_CONST DISPATCH_WARN_RESULT DISPATCH_NOTHROW
dispatch_queue_t
dispatch_get_global_queue(dispatch_queue_priority_t priority, unsigned long flags);

/*!
 * @const DISPATCH_QUEUE_SERIAL
 * @discussion A dispatch queue that invokes blocks serially in FIFO order.
 */
#define DISPATCH_QUEUE_SERIAL NULL

/*!
 * @const DISPATCH_QUEUE_CONCURRENT
 * @discussion A dispatch queue that may invoke blocks concurrently and supports
 * barrier blocks submitted with the dispatch barrier API.
 */
#define DISPATCH_QUEUE_CONCURRENT (&_dispatch_queue_attr_concurrent)
like image 150
David H Avatar answered Sep 21 '22 06:09

David H