objective-c - Objective-C 模式中的 RAII?

标签 objective-c raii exception-safety

我发现自己编写这样的代码来实现异常安全代码:

Container* container = [Container new];
@try {
    while(someCondition) {
        ElementType* value = [someObject createObjectFromStorage];
        [container add:value]; // container retains object
        [value release];
    }

    [_container release];
    _container = [container retain];
} @finally {
    [container release];
}

在 Objective-C 中是否有其他更简洁的模式可以遵循?

最佳答案

如果您只是想确保已释放对象,autorelease 可能就足够了。您还可以查看 Xcode 4.2 中新的自动引用计数选项。

一般来说,Objective-C 不适合 RAII,因为所有 Objective-C 对象都分配在堆上。这意味着对象的生命周期没有明确绑定(bind)到任何特定的堆栈帧,因此您不能依赖对象在分配它的方法结束时被释放。

您还应该知道 Cocoa 框架仅使用异常来指示程序员错误,而不是预期的错误条件。来自 Apple 的“Exception Programming Guide”文档:

Important: You should reserve the use of exceptions for programming or unexpected runtime errors such as out-of-bounds collection access, attempts to mutate immutable objects, sending an invalid message, and losing the connection to the window server. You usually take care of these sorts of errors with exceptions when an application is being created rather than at runtime.

If you have an existing body of code (such as third-party library) that uses exceptions to handle error conditions, you may use the code as-is in your Cocoa application. But you should ensure that any expected runtime exceptions do not escape from these subsystems and end up in the caller’s code. For example, a parsing library might use exceptions internally to indicate problems and enable a quick exit from a parsing state that could be deeply recursive; however, you should take care to catch such exceptions at the top level of the library and translate them into an appropriate return code or state.

事实上,因为异常旨在仅用于异常情况,默认情况下新引入的自动引用计数将 intentionally leak objects抛出异常时:

The standard Cocoa convention is that exceptions signal programmer error and are not intended to be recovered from. Making code exceptions-safe by default would impose severe runtime and code size penalties on code that typically does not actually care about exceptions safety. Therefore, ARC-generated code leaks by default on exceptions, which is just fine if the process is going to be immediately terminated anyway. Programs which do care about recovering from exceptions should enable the option.

如果您遵守该框架的惯用语,使用 Cocoa 框架进行编程会好得多。这意味着仅对程序员错误使用异常并使用 NSError 处理预期的运行时错误。大多数 Cocoa 程序员从不担心编写异常安全代码,因为他们的代码首先不会抛出异常。您可以效仿。

关于objective-c - Objective-C 模式中的 RAII?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8422704/

相关文章:

c++ - 在 C++ 中抛出后会调用析构函数吗?

java - synchronized 关键字异常安全吗?

c++ - C++ 隐式生成的赋值运算符的异常安全性

ios - 过滤 UIDocumentInteractionController 建议打开方式的应用程序

c++ - RAII 字符缓冲区

objective-c - 关于 NSStrings : Mutable and Immutable 的最后一句话

c++ - gcc 警告未使用的 RAII 变量

memory-management - 为什么析构函数会在 panic 发生时运行?

iphone - iOS 应用程序缺少屏幕截图

objective-c - 将 Xcode 项目转换为 ARC 时出现问题