objective-c - NSLocking 的使用是否应该始终包含在@try/@finally 中?

标签 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 代码这样做。

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

最佳答案

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_mutexes 和依赖于它们的实现如果你有这样的锁不平衡,可能不会表现得很优雅;这总是回退到程序员的错误。

纯 objc 和 c 中的正确和防御性锁定不是很漂亮。 Java 惯用语是正确的,同样适用于 Foundation API。您看不到它的原因可能是因为在 Cocoa API 和依赖它们的程序(与 Java 相比)中异常是一种不太流行/使用的错误处理机制。 另请参阅 Bavarious 在评论中的说明

关于objective-c - NSLocking 的使用是否应该始终包含在@try/@finally 中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7735941/

相关文章:

objective-c - 只有在 viewDidLoad 中添加的 subview 会自动调整大小

ios - UIAlerview 的 NSUserDefaults

macos - 为什么 applicationShouldOpenUntitledFile 没有被调用?

c# - 无法引用 System.ServiceModel.EndpointNotFoundException

java - 使用 Spring-Retry 指定特定于异常的退避策略

objective-c - Objective-C 中的 Gson 等价物

COCOA:NSStatusitem 图标在启动外部代码时消失

cocoa - awakeFromNib 被我的 WindowController 调用了两次,对吗?

Python - 引发异常时发送电子邮件?

objective-c - UIWebView:如何隐藏网页的部分内容?