给定一个 Cocoa NSLocking
对象(如 NSLock
)和一些在持有锁时要执行的重要代码:
要确保始终释放锁,是否应始终使用以下成语?
NSLock *mutex = // get lock from somewhere
@try {
[mutex lock];
// do non-trivial stuff
}
@finally {
[mutex unlock];
}
这看起来很谨慎(并且在 Java 中很常见),但我还没有看到任何 Cocoa 代码这样做。
应该使用这个成语吗?为什么或为什么不?
最佳答案
To ensure a lock is always released, should the following idiom always be used?
是的,在该范围之后的程序正确性(“重要的东西”)是必需的,并且假设您的程序可以从遇到的异常中正确恢复。
Should this idiom be used? Why or why not?
如果可以恢复,那么是的,需要解锁才能继续正常执行。否则,您的程序将在无效状态下执行。
示例 1:当锁被销毁时(在
dealloc
期间),销毁它的尝试将失败,因为它仍处于锁定状态。实现是继续销毁锁还是忽略错误未定义(我会猜测它会持续存在,这意味着它永远不会从dealloc
退出)。示例 2:当它被另一个线程(或同一个线程,如果不是可重入的)锁定时,您将永远不会获得锁,结果可能会产生另一个错误、死锁或异常。一个实现也可以(最终)在不获取锁的情况下继续进行。所保证的只是在/如果检测到错误时进行记录。
pthread_mutex
es 和依赖于它们的实现如果你有这样的锁不平衡,可能不会表现得很优雅;这总是回退到程序员的错误。
纯 objc 和 c 中的正确和防御性锁定不是很漂亮。 Java 惯用语是正确的,同样适用于 Foundation API。您看不到它的原因可能是因为在 Cocoa API 和依赖它们的程序(与 Java 相比)中异常是一种不太流行/使用的错误处理机制。 另请参阅 Bavarious 在评论中的说明
关于objective-c - NSLocking 的使用是否应该始终包含在@try/@finally 中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7735941/