@synchronized会锁定直到动画结束吗?
__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;
}];
}
}
}];
答案 0 :(得分:2)
没有。它只会等待方法调用的持续时间。实际动画是异步发生的,不会影响锁定。
我想如果你想要这种行为,你可以使用NSRecursiveLock并在动画的完成块中显式解锁,但这是一件非常奇怪的事情。
答案 1 :(得分:1)
不,@synchronized在其块退出时释放其锁定,这是在动画开始之前。但是在任何情况下你几乎都不想再使用@synchronized了。这是一个非常昂贵的锁。
这段代码有点奇怪。如果经理目前正在动画,你真的想丢掉更新吗?你不想搬到新目标吗?这就是Core Animation正常运作的方式;你设定了一个目标,开始制作动画,如果事情发生了变化,你只需要为这个新目标制作动画。
如果您想序列化操作,这似乎是您的目标,那么更好的工具是NSOperation
或调度队列。我可能在这里使用串行调度队列。将您想要的操作放在队列中(无论修改weakManager
)。如果您在动画完成之前不想再处理任何操作,请调用dispatch_suspend
暂停队列,并dispatch_resume
在完成块中再次启动它。
此处另一个可能有用的工具是dispatch_sempahore
,可用于代替isLocked
属性。但我建议尽可能使用队列。在大多数情况下,如果你锁定了现代的Cocoa,你就会做错事。