Objective c 在@catch块中捕获的对象的生命周期是什么?

Objective c 在@catch块中捕获的对象的生命周期是什么?,objective-c,try-catch,nsexception,Objective C,Try Catch,Nsexception,当您在ObjC@catch块中捕获异常时,该异常对象的生命周期是什么?我知道我可以安全地在街区内使用它,但是如果我想在街区后再次使用它,像这样呢 NSException * exception = nil; @try { // do something risky } @catch(NSException * e) { exception = e; } if (exception) { NSLog(@"Caught exception: %@", exception);

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

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

if (exception) {
    NSLog(@"Caught exception: %@", exception);
}
我能安全地把参考资料藏到另一个地方吗?为了安全起见,我应该保留、自动释放它吗?我可以保留它并无限期地保留它吗

(如果我分配到本地,或者以后保留和使用,它似乎可以正常工作,但是文档并没有真正讨论这个对象在所有权方面的“来源”,或者它是否特殊,所以我希望更清楚。)

继承自
NSObject
,因此,您可能可以对任何其他Objective C对象执行所有典型的操作

但是,我建议不要在你的线程之外使用它。建议:

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

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


。。。还有一些关于这些对象的有用提示。

@catch
块对生命周期毫无作用。这里的隐式约定是一个
NSException
对象,它是
-raise
'd或
@throw
n,应该是一个自动释放的对象。这意味着在
@catch
块中,提供给您的
NSException
是一个自动释放对象,就像从方法调用中获得的任何自动释放对象一样。您可以将其安全地隐藏在本地,并在
@catch
块后引用它。

NSException
采用
NSCopying
(和
NSCoding
fwiw)。如果你的生命周期有问题,并且想把这一点说清楚,那么一份拷贝将是理想的选择

我在这里停下来——放松和可可习语相互冲突。

几乎所有NSException对象(以及其他类型的异常对象)都是自动删除创建的,这会将它们分配给最近的(范围内的)自动删除池。释放该池时,将销毁异常

另外,我很确定,在中的某个地方,他们提到了名称中没有
new
alloc
copy
的方法总是按照约定返回自动释放的对象。有资格这样做

略微相关(不是NSException,而是NSError):

如果使用initWithDomain:code:userInfo:创建NSError对象,则应在将其返回给调用方之前向其发送autorelease


这本书中的建议似乎毫无用处。它只是描述了正常的内存管理策略。它描述的问题是,如果释放而不保留,或者保留而不释放(或自动释放)。如果你同时做这两件事,我想应该不会有问题。这里唯一相关的一行似乎是“所有NSException实例都放在主自动释放池中”。我希望有一个指向Apple文档的指针可以这样说,并明确说明这与从异常中展开堆栈的关系。(例如,它是在被捕获时神奇地放在顶部的自动释放池中,还是在被抛出的位置,假设该池没有被清理)我很确定这意味着当前的自动释放池如何与嵌套的自动释放池配合(如果有的话)?我知道在抛出的地方,你会抛出一个自动释放的对象,但是如果它最终通过多个嵌套的自动释放池抛出呢?如果在上路的
@finally
块中有
排水管
怎么办?如果运行时假定它运行正常,那么这个潜在的问题会被忽略吗?或者在运行时这里发生了什么特别的事情?@quixoto:如果它被扔进自动释放池,这些池就会掉在地上,不会排水。然而,由于自动释放池的工作方式,一旦外部池排水,所有落在地板上的内部池也会排水。但是是的,如果在
@finally
块中有
drain
s,那么我不确定异常的行为。有可能在抛出时被系统保留,我真的不知道。很好的参考。在那一页上还有关于异常周围的自动释放池行为的更详细的讨论,这是我主要感兴趣的棘手问题。仍然不确定“几乎所有”在那里意味着什么。也许它只是按照惯例的意思。当然,
[NSException raise…
将自动删除,但您当然可以这样做:
id foo=[[foo alloc]init];@throw foo;
我奖励您在这里获得最详细的答案。我希望在运行时对堆栈展开及其含义进行一次完全权威的讨论,因此我暂时不回答。谢谢!