4

当您在 ObjC 块中捕获异常时@catch,该异常对象的生命周期是什么?我知道我可以在块内安全地使用它,但是如果我想在块之后再次使用它怎么办,像这样?

NSException * exception = nil;
@try {
    // do something risky
} @catch(NSException * e) {
    exception = e;
}

if (exception) {
    NSLog(@"Caught exception: %@", exception);
}

我可以安全地将引用存储到另一个本地吗?retain, autorelease为了安全起见,我应该这样做吗?我可以保留它并无限期地持有它吗?

(如果我分配给本地,或者稍后保留并使用,它似乎工作正常,但是文档并没有真正讨论这个对象在所有权方面“来自”哪里,或者它是否特殊,所以我一直在寻找更清晰。)

4

4 回答 4

2

http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Exceptions/Tasks/HandlingExceptions.html

几乎所有的 NSException 对象(和其他类型的异常对象)都是自动释放的,它将它们分配到最近的(在范围内)自动释放池。当该池被释放时,异常被销毁。

另外,我很确定在内存编程指南的某处,他们提到没有newalloccopy在其名称中的方法总是按约定返回自动释放的对象。NSException 的方法有资格这样做。

稍微相关(不是 NSException 而是 NSError):

如果你使用 initWithDomain:code:userInfo: 创建一个 NSError 对象,你应该在将它返回给调用者之前发送 autorelease 给它。

http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ErrorHandlingCocoa/CreateCustomizeNSError/CreateCustomizeNSError.html

于 2011-12-11T21:52:42.877 回答
1

@catch块对生命周期完全没有任何作用。这里的隐含契约是一个'd 或n 的NSException对象应该是一个自动释放的对象。这意味着在块中,您获得的是一个自动释放的对象,就像您可能从方法调用中获得的任何自动释放的对象一样。您可以安全地将其存储在本地并在块之后引用它。-raise@throw@catchNSException@catch

于 2011-12-05T06:30:53.883 回答
0

NSException采用NSCopying(和NSCodingfwiw)。如果您的寿命有问题并且想要明确说明,那么副本将是理想的。

我停在那里 - 放松和可可成语相互流动。

于 2011-12-05T07:01:30.907 回答
0

NSException继承自NSObject,因此您可能可以做任何其他 Objective C 对象会做的所有典型事情。

但是,我建议不要在你的线程之外对它做任何事情。 这篇关于异常的 O'Reilly 文章建议:

不要使用 areleaseautoreleasemessage 来处理 NSException。NSException 的所有实例都放在主自动释放池中。手动处置实例将导致 SIGSEGV错误。

不要使用retain消息来保存 NSException。它将阻止自动释放池释放实例。这只会导致细微的内存泄漏。

...以及有关这些对象的其他一些有用的有用提示。

于 2011-12-03T01:46:28.360 回答