Как можно подавить предупреждение статического анализатора XCode Clang? - PullRequest
5 голосов
/ 10 февраля 2011

"Потенциальная утечка объекта, выделенного в строке n и сохраненного в ' переменная '."

Обычно это оченьполезное предупреждение анализатора, но есть несколько ситуаций, когда меня раздражают ложные срабатывания, которые я хотел бы подавить, чтобы сохранить результаты своего анализатора в чистоте.В защиту анализатора то, что он заметил, определенно было бы утечкой памяти, если бы не выпуск на другом пути исполнения (к которому он не обращает внимания).

Я подробно остановлюсь на моей ситуации.Это происходит в разных вариантах, но общий шаблон выглядит следующим образом:

  1. Объект выделен и его делегат установлен.
  2. Что-то сделано с объектом.(Задание запущено, отображается представление и т. Д.).
  3. Выполнение текущего метода заканчивается.(Введите предупреждение Clang).
  4. Объект решает, что его задача выполнена, отправляет делегату сообщение.
  5. Делегат освобождает объект.

Это вовсе не эзотерикашаблон дизайна, так что я надеюсь, что подавление возможно.Я знаю, что этого можно избежать, храня оскорбительный объект в иваре, который позже выпущен, но я очень предпочитаю не добавлять загрязнение ивара.

Ответы [ 3 ]

6 голосов
/ 10 февраля 2011

Clang имеет несколько новых исходных аннотаций . В частности, вас может заинтересовать атрибут ns_consumed .

1 голос
/ 10 февраля 2011

Я думаю, что в этом случае вам следует учитывать сообщение статического анализатора. У вашей модели есть потенциальные проблемы.

В частности, когда вы возвращаетесь из метода, вызванного для выполнения шага 5, вы находитесь в методе объекта, который, возможно, уже был освобожден. Я интерпретирую ваш шаблон примерно так:

// steps 1, 2, 3
-(void) methodThatCreatesObject
{
    id theObj = [[TheObj alloc] init];
    [theObj setDelegate: delegateObj];
    // other stuff
}

Обратите внимание, что вышеприведенные нарушения правил управления памятью

// step 4 - a method of theObj
-(void) someMethod
{
    [delegate notifyTaskCompleteFromObj: self];
    // self points to an invalid object here.  Doing anything with self results in EXC_BAD_ACCESS
}

Вышеупомянутое нарушает предположение, изложенное в правилах управления памятью:

Полученный объект обычно гарантированно остается действительным в методе, который был получен в

, если мы говорим self - это полученный объект, которым он является технически, поскольку он передается в качестве параметра в стеке.

// step 5 the delegate method defined in the delegate object

-(void) notifyTaskCompleteFromObj: (TheObj*) anObj
{
    // do stuff
    [anObj release];
}

Вышеуказанное также нарушает правила управления памятью.

Обычный шаблон - иметь контроллер, которому принадлежит и делегат, и объект, который имеет делегата (часто контроллер сам является делегатом). Я думаю, что вы должны перейти к этому шаблону.

0 голосов
/ 08 сентября 2011

Еще одна интересная опция пришла мне в голову. ОП дала следующий сценарий:

  1. Объект выделен и его делегат установлен.
  2. Что-то сделано с объектом. (Задача запущена, вид отображается и т. Д.).
  3. Выполнение текущего метода заканчивается. (Введите Clang предупреждение).
  4. Объект решает, что его задача выполнена, отправляет делегату сообщение.
  5. Делегат освобождает объект.

Если вместо явного выпуска вы просто хотели продлить время жизни выделенного объекта до времени существования объекта выделения / удаления, вы можете сделать следующее:

TheObject* foo = [[TheObject alloc] init] autorelease];
foo.delegate = self;
[foo doSomething];
objc_setAssociatedObject(self, foo, foo, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
return;

Устанавливая foo в качестве связанного объекта с политикой хранения, делегат (self) будет эффективно сохранять объект, который впоследствии будет освобожден всякий раз, когда делегат (self) будет освобожден (позже).

Это не ТОЧНО то, о чем просил ОП, но, тем не менее, это полезная модель, и кажется, что этого будет достаточно в ситуации, представленной ОП.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...