Assuming you're trying to synchronize the interaction with this myID
object in the background queue, you want it the other way around, the lock inside the dispatched block. Right now you have:
@synchronized(myID) {
dispatch_async(queue, ^{
// do stuff with myID
});
}
That's synchronizing the process of adding the dispatched block to your queue, but does not synchronize what you're doing in the background. I suspect that's not what you meant.
You probably intended:
dispatch_async(queue, ^{
@synchronized(myID) {
// do stuff with myID
}
});
It looks very similar, but results in an entirely different behavior. Now, the work dispatched to the background queue is being synchronized.
As a further refinement, if this dispatched block is possibly slow (and I assume it may be), then you'd probably want to constrain the @synchronized
block as much as possible:
dispatch_async(queue, ^{
// do slow stuff in preparation for interacting with `myID`
@synchronized(myID) {
// quickly do stuff with myID
}
// do anything else here
});
If you do all of the background block within a @synchronized
block, you may defeat the entire purpose for dispatching it to the background, namely to minimize impact on the main queue. This last rendition mitigates that problem.
As a final observation, if you have a serial queue (or a non-global concurrent queue in which you do updates with a barrier), that's often used as a technique that eliminates the need for locks altogether, as long as all updates and inquiries for myID
are dispatched to that queue. See Eliminating Lock-Based Code in the Concurrency Programming Guide.
myID
at any point? The@synchronized
block is unique to that particular instance of the object pointed to bymyID
, not the variable in general. – Moya