NSLocking的使用总是应该包含在@ try / @中吗?

时间:2011-10-12 06:08:53

标签: objective-c cocoa exception-handling locking

给定一个Cocoa NSLocking对象(如NSLock)和一些在执行锁定时要执行的非平凡代码:

为了确保始终释放锁定,是否应始终使用以下习语?

NSLock *mutex = // get lock from somewhere
@try {
    [mutex lock];
    // do non-trivial stuff
} 
@finally {
    [mutex unlock];
}

这看起来很谨慎(在Java中很常见),但我没有看到任何Cocoa代码这样做。

这个成语应该被使用吗?为什么或为什么不呢?

2 个答案:

答案 0 :(得分:4)

  

为了确保始终释放锁定,是否应始终使用以下习语?

是的,需要在该范围之后的程序正确性('非平凡的东西'),并假设您的程序可以从遇到的异常中正确恢复。

  

这个成语应该被使用吗?为什么或为什么不呢?

如果你可以恢复,那么是,解锁是必要的,以继续正常执行。否则,您的程序将以无效状态执行。

  • 示例1:当锁被销毁时(在dealloc期间),销毁它的尝试将失败,因为它仍然被锁定。是否继续销毁锁定或忽略错误未定义(我会猜测它会持续存在,这意味着它永远不会从dealloc退出。)

  • 示例2:当它从另一个线程(或同一个线程,如果不是可重入的)锁定时,您将永远不会获得锁定,因此可能会产生另一个错误,死锁或异常。实施也可以(最终)在没有获得锁定的情况下继续进行。所有保证都是在检测到错误时进行记录。

如果你有这样的锁不平衡,

pthread_mutex和依赖于它们的实现可能不会非常优雅;这总是会回到程序员错误。

纯粹的objc和c中的正确和防御锁定不是很漂亮。 Java习语是正确的,同样适用于Foundation API。您没有看到它的原因可能因为异常是Cocoa API和依赖它们的程序(与Java相比)中不太流行/使用的错误处理机制。 另见评论中的Bavarious'注释

答案 1 :(得分:3)

没有

异常仅用于Cocoa中的编程错误。它们不适用于预期程序恢复的情况。