Reputation: 8546
Will the @synchronized lock until the end of the animation?
__weak typeof(sharedManager) weakManager = sharedManager;
^(CMDeviceMotion *motion, NSError *error)
{
@synchronized(weakManager)
{ ... some code
if (angle != sharedManager.angle)
{
if (sharedManager.isLocked) return;
sharedManager.locked = YES;
sharedManager.angle = angle;
CGAffineTransform transform = (angle == 0) ?
CGAffineTransformIdentity : CGAffineTransformMakeRotation(angle);
sharedManager.currentTransform = transform;
[UIView animateWithDuration:.25
animations:^
{
[weakManager.animatedViews setValue:[NSValue valueWithCGAffineTransform:transform]
forKey:@"transform"];
}
completion:^(BOOL finished)
{
weakManager.locked = NO;
}];
}
}
}];
Upvotes: 0
Views: 214
Reputation: 56635
No. It will only wait for the duration of the method call. The actual animation happens a asynchronously and doesn't affect the lock.
I guess that if you wanted that behavior, you could use a NSRecursiveLock and explicitly unlock in the completion block of the animation but that's a pretty strange thing to do.
Upvotes: 2
Reputation: 299545
No, @synchronized releases its lock when its block exits, which is before the animations here begin. But you almost never want to use @synchronized anymore in any case. It's a very expensive lock.
This code is a bit strange. Do you really want to throw away the update if the manager is currently animating? Wouldn't you want to move to the new target? That's how Core Animation normally works; you set a target, start animating, and if things change you just animate towards that new target.
If you want to serialize operations, which seems to be your goal, then the better tools are NSOperation
or dispatch queues. I'd probably use a serial dispatch queue here. Put the action you want on the queue (whatever modifies weakManager
). If you don't want any more actions to process until the animation is done, then call dispatch_suspend
to suspend the queue, and dispatch_resume
to start it again in the completion block.
the other potentially useful tool here is a dispatch_sempahore
, which can be used in place of the isLocked
property. But I'd recommend just using a queue if possible. In most cases, if you're locking in modern Cocoa, you're doing something wrong.
Upvotes: 1