给定一个Cocoa NSLocking
对象(如NSLock
)和一些在执行锁定时要执行的非平凡代码:
为了确保始终释放锁定,是否应始终使用以下习语?
NSLock *mutex = // get lock from somewhere
@try {
[mutex lock];
// do non-trivial stuff
}
@finally {
[mutex unlock];
}
这看起来很谨慎(在Java中很常见),但我没有看到任何Cocoa代码这样做。
这个成语应该被使用吗?为什么或为什么不呢?
答案 0 :(得分:4)
为了确保始终释放锁定,是否应始终使用以下习语?
是的,需要在该范围之后的程序正确性('非平凡的东西'),并假设您的程序可以从遇到的异常中正确恢复。
这个成语应该被使用吗?为什么或为什么不呢?
如果你可以恢复,那么是,解锁是必要的,以继续正常执行。否则,您的程序将以无效状态执行。
示例1:当锁被销毁时(在dealloc
期间),销毁它的尝试将失败,因为它仍然被锁定。是否继续销毁锁定或忽略错误未定义(我会猜测它会持续存在,这意味着它永远不会从dealloc
退出。)
示例2:当它从另一个线程(或同一个线程,如果不是可重入的)锁定时,您将永远不会获得锁定,因此可能会产生另一个错误,死锁或异常。实施也可以(最终)在没有获得锁定的情况下继续进行。所有保证都是在检测到错误时进行记录。
pthread_mutex
和依赖于它们的实现可能不会非常优雅;这总是会回到程序员错误。
纯粹的objc和c中的正确和防御锁定不是很漂亮。 Java习语是正确的,同样适用于Foundation API。您没有看到它的原因可能因为异常是Cocoa API和依赖它们的程序(与Java相比)中不太流行/使用的错误处理机制。 另见评论中的Bavarious'注释
答案 1 :(得分:3)
没有
异常仅用于Cocoa中的编程错误。它们不适用于预期程序恢复的情况。