What is the lifecycle of an object caught in a @catch block?

 ̄綄美尐妖づ 提交于 2019-12-10 17:24:28

问题


When you catch an exception in an ObjC @catch block, what is the lifecycle of that exception object? I know I can safely use it inside the block, but what if I want to use it again after the block, like this?

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

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

Can I safely stash the reference into another local? Should I be retain, autoreleaseing it for safety? Can I retain it and hold onto it indefinitely?

(It does seem to work OK if I assign to the local, or retain and use later, but the docs don't really discuss where this object "comes from" in terms of ownership, or if it's special, so I was looking for more clarity.)


回答1:


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

Almost all NSException objects (and other types of exception objects) are created autoreleased, which assigns them to the nearest (in scope) autorelease pool. When that pool is released, the exception is destroyed.

Also, I'm pretty sure that somewhere in the memory programming guide, they mention that methods without new or alloc or copy in their names always return autoreleased objects by convention. NSException's methods qualify for that.

Slightly related (not NSException but NSError):

If you create an NSError object with initWithDomain:code:userInfo:, you should send autorelease to it before you return it to the caller.

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




回答2:


@catch blocks do absolutely nothing for lifecycle. The implicit contract here is an NSException object that is -raise'd or @thrown should be an autoreleased object. This means that in the @catch block, the NSException that you are given is an autoreleased object, just like any autoreleased object you might get from a method call. You can safely stash it in a local and reference it after the @catch block.




回答3:


NSException inherits from NSObject, so you can probably do all the typical things one would do with any other Objective C object.

However, I'd recommend not doing anything with it outside of your thread. This O'Reilly article about Exceptions suggests:

Do not use a release or an autorelease message to dispose an NSException. All instances of NSException are placed in the main autorelease pool. Manually disposing an instance will result in a SIGSEGV error.

Do not use a retain message to preserve an NSException. It will prevent the autorelease pool from disposing the instance. This will only result in a subtle memory leak.

... and some other useful helpful hints on these objects.




回答4:


NSException adopts NSCopying (and NSCoding fwiw). If you are in a case of questionable lifetime and want to make that explicit, a copy would be ideal.

I'm stopping there - unwinding and cocoa idioms flow against each other.



来源:https://stackoverflow.com/questions/8364834/what-is-the-lifecycle-of-an-object-caught-in-a-catch-block

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!