Tod*_*orf 11 cocoa locking exception-handling objective-c
给定一个Cocoa NSLocking对象(比如一个NSLock)和一些在执行锁定时要执行的非平凡代码:
为了确保始终释放锁定,是否应始终使用以下习惯用法?
NSLock *mutex = // get lock from somewhere
@try {
[mutex lock];
// do non-trivial stuff
}
@finally {
[mutex unlock];
}
Run Code Online (Sandbox Code Playgroud)
这似乎是谨慎的(在Java中很常见),但我没有看到任何Cocoa代码这样做.
应该使用这个成语吗?为什么或者为什么不?
为了确保锁始终被释放,是否应该始终使用以下习惯用法?
是的,在该范围(“非平凡的东西”)之后的程序正确性是必需的,并且假设您的程序可以正确地从遇到的异常中恢复。
应该使用这个习语吗?为什么或者为什么不?
如果可以恢复,那么是的,需要解锁才能继续正常执行。否则,您的程序将在无效状态下执行。
示例 1:当锁被销毁时(在 期间dealloc),销毁它的尝试将失败,因为它仍然处于锁定状态。未定义实现是否继续破坏锁或忽略错误(我猜它会持续存在,这意味着它永远不会退出dealloc)。
示例 2:当它被另一个线程(或同一个线程,如果不可重入)锁定时,您将永远不会获取该锁,并且可能会产生另一个错误、死锁或异常。实现也可以(最终)在不获取锁的情况下继续进行。所保证的只是在检测到错误时/如果检测到错误时进行记录。
pthread_mutex如果你有这样的锁不平衡,es 和依赖它们的实现可能不会表现得非常优雅;这总是会归咎于程序员的错误。
纯 objc 和 c 中的正确和防御性锁定并不是很漂亮。Java 习惯用法是正确的,并且同样适用于 Foundation API。您没有看到太多的原因可能是因为异常是 Cocoa API 和依赖它们的程序中不太流行/使用的错误处理机制(与 Java 相比)。另请参阅评论中巴伐利亚的注释