Intereting Posts
Как правильно инициализировать ViewController программно? loadView () vs init (nibName: nil, bundle: nil) Cocoapods 1.0: те же самые стручки для нескольких целей Firebase: Загруженная временная метка, созданная FIRServerValue.timestamp (), немного отличается от онлайн-версии библиотека не найдена для -lPods-test clang при компиляции модульных тестов Создание единого времени для GPUImage Выбор аннотации MapView дважды Ошибки отправки обновленной версии для перенесенного приложения iOS Различные отпечатки пальцев с использованием Touch ID в ios Невозможно вызвать 'fetch' с помощью списка аргументов типа '(NSFetchRequest <NSFetchRequestResult>)' Xcode | Ошибка получения информации о разработчике Анимация представления при добавлении / удалении из подвью Как изменить изображение и заголовок TabBarItem Приложение BLE iOS – несоответствие при выборке с высокой скоростью iOS LPCM Неперемещаемый аудиовход с двумя каналами: невозможно? WatchKit: вызов popToRootController после нажатия пользователем кнопки отмены (отмены) в верхнем левом углу

Как очистить статический анализатор Clang, когда что-то не просачивается?

При использовании статического анализатора Clang для анализа моего кода Objective-C для iOS я получаю много «потенциальных утечек». Многие утечки заставляют меня задаться вопросом, почему это вообще ошибочно. Один из примеров, в результате которого я, в частности, задавался вопросом:

У меня есть переменная класса типа NSDictionary , используемая для хранения некоторых параметров. Теперь, когда у меня есть способ изменить что-то внутри словаря:

 - (void) loadPassengerCompartiments { NSMutableArray *paxCompartiments = [self.outputTable objectAtIndex:2]; NSArray *paxCompSrc = [self.values objectForKey:@"PassengerCompartiments"]; for(MassPerson *passenger in paxCompSrc) { => [paxCompartiments addObject:[[PaxCompartimentOutputField alloc] initWithPerson:passenger]]; } } 

Clang ошибается при линейном распределении и прямой ассоциации PaxCompartimentOutputField . При запуске этого кода в инструментах он не течет.

Два способа, которые я мог бы решить, это:

  1. использовать autorelease
  2. замените выделение в строке следующим кодом:

(код)

 PaxCompartimentOutputField *field = [[PaxCompartimentOutputField alloc] initWithPerson:passenger]; [paxCompartiments addObject:field]; [field release]; 

Первый вариант – устаревший imho (и особенно в iOS его использование не рекомендуется). Второй вариант довольно громоздкий – особенно при создании массива с большим количеством объектов (например, 10 объектов, загружающих настройки по умолчанию).

Я не хочу игнорировать предупреждения Клана, так как это отличный инструмент для поиска ошибок и утечек. Каков «правильный» способ сделать это в Objective-C для этих случаев?

Это утечка.

Поскольку вы выделяете-init PaxCompartimentOutputField , вы владеете им, и вы должны отказаться от права собственности на него.

У вас есть 3 варианта (вы уже упоминали 2 из них):

1) Используйте конструктор удобства , когда он доступен, или в пользовательском классе, объявите его. Конструкторы autorelease возвращают объекты, которым вы не владеете , обычно отправляя сообщение autorelease на возвращаемый объект. Это будет выглядеть так:

 [paxCompartiments addObject:[PaxCompartimentOutputField paxCompartimentOutputWithPerson:passenger]]; 

2) Используйте autorelease .

 [paxCompartiments addObject:[[[PaxCompartimentOutputField alloc] initWithPerson:passenger]] autorelease]; 

3) Используйте временную переменную.

 PaxCompartimentOutputField *tempField = [[PaxCompartimentOutputField alloc] initWithPerson:passenger]; [paxCompartiments addObject:tempField]; [tempField release]; 

Существует список исходных аннотаций, которые вы можете использовать с Clang.

Это может помочь.