Нужно ли выпускать IBOutlets при использовании loadNibNamed: метод? - PullRequest
17 голосов
/ 20 декабря 2008

У меня есть файл .xib, содержащий подвиды UIView и 2 UILabel, связанные с классом с именем Note, с выходами, назначенными для каждой метки соответствующим образом, определение этого класса содержит следующее.

@interface Note : UIView {
    IBOutlet UILabel *time;
    IBOutlet UILabel *content;
}

Я строю это с помощью следующего кода

NSArray* nibViews = [[NSBundle mainBundle] loadNibNamed:@"Note" owner:self options:nil];
note = [nibViews lastObject];
[self addSubview:note];

Теперь, на этапе освобождения класса Note я не выпускаю ни время, ни контент, но мне интересно, должен ли я?

- (void)dealloc {
    [super dealloc];
}

Я предполагаю, что нет, потому что я явно не сохраняю эти объекты в моем коде и не синтезирую их в методы получения / установки. Но я не знаю достаточно о разборке пера, чтобы знать, должен ли я выпускать их в фазе деаллока или нет?

Ответы [ 5 ]

14 голосов
/ 09 ноября 2009

Вы должны выпустить IBOutlet, даже если вы не пишете или синтезируете методы доступа. В документации по жизненному циклу NIB говорится, что, хотя для неархивированных объектов изначально задано автоматическое высвобождение, счетчик их хранения увеличивается на 1, когда UIKit подключает все привязки соединения IBOutlet. Поэтому вам нужно вручную уменьшить значение через релиз, когда вы закончите.

Не очевидно, что UIKit будет делать это, поэтому вы можете предположить, что можете просто оставить методы setter / getter отключенными и верить, что все автоматически выпущено. Но это не так.

Обратите внимание, что шаблоны Interface Builder явно освобождают любые IBOutlets, поэтому любые добавляемые вами элементы должны обрабатываться аналогично.

2 голосов
/ 20 декабря 2008

Это правильно для iPhone; это не будет правильно на Mac, хотя.

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

0 голосов
/ 09 мая 2012

Вы не сможете извлечь их из памяти, если не объявите IBOutlets как свойства и не синтезируете их в ivars:

@interface Note : UIView {
    IBOutlet UILabel *time;
    IBOutlet UILabel *content;
}

@property (nonatomic, retain) IBOutlet UILabel *time;
@property (nonatomic, retain) IBOutlet UILabel *content;

@end


@implementation Note
@synthesize time, content;

// your methods

- (void)dealloc {
     [time release], time = nil;
     [content release], content = nil;
     [super dealloc];
}

@end
0 голосов
/ 22 декабря 2008

Вы должны отпустить его. См

"Однако при перестройке иерархии объектов UIKit восстанавливает соединения между объектами с помощью метода setValue: forKey:, который использует доступный метод setter или сохраняет объект по умолчанию, если метод setter недоступен." в Сохранение объекта Nib

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

В методе dealloc () вы должны установить для всех IBOutlets значение nil, используя

self.outletName = nil;

Если сеттер не определен, то setValue автоматически выпустит старое значение (убедитесь, что у вас есть NSAutoreleasePool, если он работает в потоке). Если сеттер определен, он будет выполнять любое поведение, которое вы определили. В любом случае, установка на ноль будет делать абсолютно правильно, и гарантирует, что вы не получите утечки памяти. НЕ делайте этого

outletName = nil;

Это будет непосредственно устанавливать переменную-член и обходить вызов setValue.

Подробнее см. Документацию по NSObject setValue: forKey.

Запуск Performance Tool (Leaks) не покажет утечку, но вы можете проверить, есть ли на самом деле утечка, посмотрев текущий текущий суммарный объем выделенной памяти.

cf The Airsource - Управление памятью и NIB

0 голосов
/ 20 декабря 2008

Я верю, что вы правы. См. Ссылки на документацию ниже для более подробной информации.

Документация:

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