Почему "try catch" в Objective-C вызывает утечку памяти?

Я думаю о плюсах и минусах Try-Catch в Objective-C. Согласно этой статье Dispelling NSException Myths в iOS: можем ли мы использовать @try... @catch, @finally?, try-catch не так уж плох, за исключением того, что он пропускает память в ARC.

Итак, как попытка try-catch вызывать утечку памяти?

Ответ 1

Прежде всего: исключения имеют различную семантику в Objective-C. Исключение означает, что что-то пошло не так из-за ошибки программирования, и дальнейшее выполнение приложения бесполезно. Прекрати это! Для обработки "ожидаемых ошибок" (таких как недостаточный ввод данных пользователем или не отвечающие серверы и др.) Используйте шаблон обработки ошибок Cocoa. (Причина этого в том, что исключения кажутся удобными во многих ситуациях, но их очень трудно обрабатывать в других ситуациях, например, во время конструирования объекта. Прочитайте об исключениях в C++. Это больно.)

К вашему Q: ARC добавляет дополнительный код для управления памятью. Этот код должен быть выполнен для управления памятью, особенно выпустить объекты. Если исключение происходит до того, как это будет сделано, поток управления никогда не достигнет оператора release. Утечки памяти.

- (void)method
{
   id reference = …;
   // Some ARC code to retain the object, reference points to.
   … 
   @throw …
   …
   // reference loses its extent, because of method termination
   // Some ARC code to release the object, reference points to.
}

Если у вас есть исключение, метод немедленно покидается, и код ARC и конец метода для освобождения объекта никогда не выполняются. Это утечка.

Вы можете изменить это поведение, скомпилировав исходный код с -fobjc-arc-exceptions.

http://clang.llvm.org/docs/AutomaticReferenceCounting.html#exceptions

Это добавит код, чтобы сделать ARC-исключение безопасным, вызывая штраф за время выполнения. Но в разработке Cocoa нет особых причин, как объяснялось в начале этого ответа.