Xcode «Анализировать» сообщение путаницы

Я унаследовал старый проект Objective C, который не использует ARC, и из-за использования сторонних библиотек может использовать ARC.

Я пытаюсь разрешить ряд случайных сбоев, вызванных доступом un / deallocated memory.

Одна из моих первых задач заключалась в том, чтобы запустить инструмент «Анализ» Xcode и посмотреть, какие проблемы он обнаружил. По большей части было очень полезно и в основном здравый смысл для решения проблем.

Однако у меня есть несколько классов (а именно пользовательские UITableViewCell s), которые вызывают у меня некоторые проблемы, и я не знаю, как решить проблемы

Потенциальная утечка объекта

Фактический класс

 #import "userListView.h" @implementation userListView @synthesize userCustomCelltextlabel,userCustomDetailtextlabel; @synthesize unreadIdentifierImg; -(void)dealloc { [userCustomCelltextlabel release]; [userCustomDetailtextlabel release]; [unreadIdentifierImg release]; [super dealloc]; } - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; if (self) { self.unreadIdentifierImg=[[UIImageView alloc]initWithFrame:CGRectMake(165,1,12,38)]; self.userCustomCelltextlabel=[[UILabel alloc]initWithFrame:CGRectMake(12,5,150,20)]; self.userCustomCelltextlabel.font=[UIFont fontWithName:@"TrebuchetMS-Bold" size:13.0f]; self.userCustomCelltextlabel.backgroundColor=[UIColor clearColor]; self.userCustomDetailtextlabel=[[UILabel alloc]initWithFrame:CGRectMake(12,22,150,15)]; self.userCustomDetailtextlabel.backgroundColor=[UIColor clearColor]; self.userCustomDetailtextlabel.textColor=[UIColor grayColor]; self.userCustomDetailtextlabel.font=[UIFont fontWithName:@"Trebuchet MS" size:12.0]; self.userCustomDetailtextlabel.numberOfLines=1; self.userCustomDetailtextlabel.lineBreakMode=NSLineBreakByTruncatingTail; //self.unreadIdentifierImg.image=[UIImage imageNamed:@"MessageEntrySendButton.png"]; //self.unreadIdentifierImg.hidden=YES; [self.contentView addSubview:self.unreadIdentifierImg]; [self.contentView addSubview:self.userCustomDetailtextlabel]; [self.contentView addSubview:self.userCustomCelltextlabel]; } return self; } - (void)setSelected:(BOOL)selected animated:(BOOL)animated { [super setSelected:selected animated:animated]; // Configure the view for the selected state } @end 

И заголовок

 #import <UIKit/UIKit.h> @interface userListView : UITableViewCell @property (retain, nonatomic) UILabel *userCustomCelltextlabel; @property (retain, nonatomic) UILabel *userCustomDetailtextlabel; @property (retain, nonatomic) UIImageView *unreadIdentifierImg; @end 

Расширение ошибок показывает …

 // 2. Method returns an instance of UIImageView with a +1 retain count self.unreadIdentifierImg=[[UIImageView alloc]initWithFrame:CGRectMake(165,1,12,38)]; // Seems to point to UIImageView init // 3. Object leaked: allocated object is not referenced later in this execution path and has a retain count of +1 self.userCustomCelltextlabel=[[UILabel alloc]initWithFrame:CGRectMake(12,5,150,20)]; // Which seems to point to the UILabel init 

И повторяется для userCustomDetailtextlabel . Проблема, которую я имею здесь, – это allocated object is not referenced later in this execution path , что неверно, поскольку оно добавлено в contentView .

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

Должен ли я игнорировать их? Есть ли что-то еще, что я должен изучить, чтобы попытаться их решить?

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

Вы создаете ярлыки с alloc / init, что дает метку с сохранением числа +1, после чего вы присваиваете ее свойству, используя self.userCustomCelltextlabel это вызывает метод соответствующего метода установки, который отправляет сохранение на метку, теперь это имеет показатель сохранения +2.

В dealloc вы отправляете релиз, а метка имеет счет сохранения +1 и протекает.

Добавьте autorelease в ваш alloc / init или назначьте ее ivar непосредственно с помощью _userCustomCelltextlabel .

Если это первый случай, когда вы столкнулись с ручным управлением памятью в Objective-C, также называемом «ручным удержанием», и если этот проект не может быть перенесен в ARC, я могу только предположить, что вы чтобы узнать о ручном управлении памятью. Страница «Управление памятью» в руководстве «Основные компетенции Cocoa» и страница «Практическое управление памятью» в Руководстве по программированию расширенного управления памятью – это два хороших места для запуска.

К сожалению, ручное управление памятью в целом слишком велико, чтобы быть в хорошей форме для ответа на переполнение стека, но я объясню, что происходит для одного из этих объектов – в этой строке:

 self.unreadIdentifierImg = [[UIImageView alloc] initWithFrame:CGRectMake(165,1,12,38)]; 

Когда вы вызываете [[UIImageView alloc] initWithFrame: ... ]; вы выделяете память и создаете новый объект. В соответствии с политикой владения какао вы «владеете» этим объектом и несете ответственность за свою память, так как вы вызвали alloc . В этот момент этот вновь созданный объект имеет значение сохранения 1.

Когда вы назначаете этот объект self.unreadIdentifierImg он сохранит объект, который ему назначен. Это происходит потому, что свойство определяется как @property (retain, nonatomic) ... Это удерживает счетчик объектов, что означает, что теперь он равен 2.

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

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

Чтобы исправить это, вы захотите выпустить его один раз после того, как он был назначен сохранению. Скорее всего, вы сделаете это путем «автоматического освобождения», что означает, что объект будет добавлен в текущий пул авторесурсов – будет выпущен позднее, когда пул будет удален:

 self.unreadIdentifierImg = [[[UIImageView alloc] initWithFrame:CGRectMake(165,1,12,38)] autorelease]; 

Обратите внимание, что это добавленный вызов autorelease в конце этой строки.


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

  • iOS - Жест и uislider
  • Возможно ли переместить элемент раскадровки из компактного - обычного в любой - любой?
  • Как изменить порядок ячеек под UITests?
  • Ошибка Xcode NSTimer: непризнанный селектор, отправленный в класс
  • Почему в Xcode 9.x отсутствует симулированная метрика состояния?
  • Xcode 7.2.1 Пользовательский шрифт в интерфейсе bulilder
  • Если метки равны, измените вид
  • Определение, где в коде произошла ошибка - iPhone
  • Кнопка управления несколькими навигационными контроллерами
  • Предупреждение после обновления до xcode 4.6 и iOS 6.1 Используется как имя предыдущего параметра, а не как часть селектора
  • Проблемы с размером текста UIButton
  • Interesting Posts

    Прекратить увольнение в анимационном режиме для MPMoviePlayerViewController?

    Draw / Doodle / Аннотировать существующее изображение в Swift

    Возможно получить рекламу Beacon в IOS без использования идентификатора компании Apple 0x004c

    Несколько таблиц в одном контроллере просмотра

    Прочитать файл в каталоге проекта из собственного кода iOS?

    iOS: содержимое ячеек не очищается с помощью повторного использования

    Отладка EXC_BAD_ACCESS – Objective-C – Xcode 8.0

    Core Text: Drop caps + styles styles: Несовместимо?

    Как написать расширение для NSFetchedResultsController в Swift 4

    Сбой UIAlertController (SIGABRT) при добавлении второго действия

    Что значит AudioUnitRender?

    Методы UNUserNotificationCenterDelegate не называются Xcode 8 iOS 10

    Нарисуйте CGContext с CGImage

    Повторное использование детального контроллера представления в UISplitViewController

    Получение '- : метод мутации, отправленный в неизменяемый объект, при попытке изменить порядок ячеек в UITableView

    Давайте будем гением компьютера.