Каков жизненный цикл объекта, пойманного в блоке @catch? - PullRequest
4 голосов
/ 03 декабря 2011

Когда вы ловите исключение в блоке ObjC @catch, каков жизненный цикл этого объекта исключения? Я знаю, что могу безопасно использовать его внутри блока, но что, если я захочу использовать его снова после блока, как это?

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

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

Могу ли я безопасно спрятать ссылку в другой локальный? Должен ли я сделать это для безопасности? Могу ли я сохранить его и удерживать до бесконечности?

(Похоже, что все работает нормально, если я назначу локальному, или сохраню и использую позже, но в документах не обсуждается, откуда этот объект "происходит" с точки зрения владения или если он особенный, поэтому искал больше ясности.)

Ответы [ 4 ]

2 голосов
/ 12 декабря 2011

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

Почти все объекты NSException (и другие типы объектов исключений) создаются с автоматическим освобождением, что присваивает их ближайшему (в области действия) пулу автоматического выпуска.Когда этот пул освобождается, исключение уничтожается.

Кроме того, я почти уверен, что где-то в руководстве по программированию памяти они упоминают, что методы без new илиalloc или copy в их именах всегда возвращают автоматически выпущенные объекты по соглашению. Методы NSException соответствуют этим требованиям.

Немного связано (не NSException, а NSError):

Если вы создаете объект NSError с initWithDomain: code: userInfo :,Вы должны отправить авто-релиз на него, прежде чем вернуть его вызывающей стороне.

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

1 голос
/ 05 декабря 2011

@catch блоки не делают абсолютно ничего в течение жизненного цикла.Под неявным контрактом здесь понимается NSException объект, который -raise 'd или @throw n должен быть автоматически выпущенным объектом.Это означает, что в блоке @catch заданный вами NSException является автоматически выпущенным объектом, так же как и любой автоматически выпущенный объект, который вы можете получить из вызова метода.Вы можете безопасно хранить его в локальном каталоге и ссылаться на него после блока @catch.

0 голосов
/ 05 декабря 2011

NSException принимает NSCopyingNSCoding fwiw).Если у вас сомнительная продолжительность жизни и вы хотите сделать это явным, копия будет идеальной.

Я останавливаюсь там - раскручивание и идиомы какао текут друг против друга.

0 голосов
/ 03 декабря 2011

NSException наследуется от NSObject, так что вы, вероятно, можете делать все типичные вещи, которые можно сделать с любым другим объектом Objective C.

Однако я бы не советовал ничего делать с этим вне вашей ветки. Эта статья О'Рейли об исключениях предлагает:

Не используйте сообщения release или autorelease для удаления исключения NSE.Все экземпляры NSException помещаются в основной пул авто-релизов.Удаление экземпляра вручную приведет к ошибке SIGSEGV.

Не используйте сообщение retain для сохранения исключения NSE.Это предотвратит удаление пула автоматического выпуска экземпляром.Это приведет только к незначительной утечке памяти.

... и другим полезным подсказкам по этим объектам.

...