Нужно ли освобождать ресурсы XIB? - PullRequest
37 голосов
/ 15 сентября 2008

Если у меня есть что-то вроде UILabel, связанное с XIB-файлом, нужно ли мне выпускать его по аналогии с моим видом? Причина, по которой я спрашиваю, состоит в том, что я не выделяю ее, что заставляет меня думать, что мне тоже не нужно ее выпускать? например (в шапке):

IBOutlet UILabel *lblExample;

в реализации:

....
[lblExample setText:@"whatever"];
....

-(void)dealloc{
    [lblExample release];//?????????
}

Ответы [ 8 ]

35 голосов
/ 10 октября 2008

Если вы следуете тому, что в настоящее время считается лучшей практикой, вы должны освободить свойства розетки, поскольку вы должны были сохранить их в наборе доступа:

@interface MyController : MySuperclass {
    Control *uiElement;
}
@property (nonatomic, retain) IBOutlet Control *uiElement;
@end


@implementation MyController

@synthesize uiElement;

- (void)dealloc {
    [uiElement release];
    [super dealloc];
}
@end

Преимущество этого подхода состоит в том, что он делает семантику управления памятью явной и понятной и работает согласованно на всех платформах для всех nib-файлов .

Примечание. Следующие комментарии относятся только к iOS до версии 3.0. В версии 3.0 и более поздних вы должны просто обнулять значения свойств в viewDidUnload.

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

- (void)setView:(UIView *)newView {
    if (newView == nil) {
        self.uiElement = nil;
    }
    [super setView:aView];
}

К сожалению, это порождает еще одну проблему. Поскольку UIViewController в настоящее время реализует свой метод dealloc, используя метод доступа setView: (а не просто освобождает переменную напрямую), self.anOutlet = nil будет вызываться как в dealloc, так и в ответ на предупреждение памяти ... Это привести к краху в dealloc.

Средство защиты должно обеспечить, чтобы переменные выхода также были установлены на nil в dealloc:

- (void)dealloc {
    // release outlets and set variables to nil
    [anOutlet release], anOutlet = nil;
    [super dealloc];
}
4 голосов
/ 15 сентября 2008

Я нашел то, что искал в документации Apple. Короче говоря, вы можете настроить ваши объекты как свойства, которые вы освобождаете и сохраняете (или просто @property, @synthesize), но вам не нужно это делать для таких вещей, как UILabels:

http://developer.apple.com/iphone/library/documentation/Cocoa/Conceptual/LoadingResources/CocoaNibs/chapter_3_section_4.html#//apple_ref/doc/uid/10000051i-CH4-SW18

3 голосов
/ 20 февраля 2009

[anOutlet release], anOutlet = nil;

Часть совершенно лишняя, если вы написали setView: правильно.

1 голос
/ 19 февраля 2010

Если вы не отпустите его на dealloc, это увеличит объем памяти.

Подробнее смотрите здесь с графиком ObjectAlloc инструмента

0 голосов
/ 13 апреля 2012

Если вы не устанавливаете IBOutlet как свойство, а просто как переменную экземпляра, вы все равно должны освободить его. Это связано с тем, что после initWithNib память будет выделена для всех IBOutlets. Так что это один из особых случаев, который вы должны освободить, даже если вы не сохранили или не распределили память в коде.

0 голосов
/ 15 сентября 2008

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

0 голосов
/ 15 сентября 2008

Вы в некотором смысле выделяете метку, создавая ее в IB.

Что делает IB, это смотрит на ваши IBOutlets и как они определены. Если у вас есть переменная класса, которой IB должен присвоить ссылку на какой-либо объект, IB отправит вам сообщение сохранения для этого объекта.

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

@property (nonatomic, retain) UILabel *lblExample;

Таким образом, в случае эфира (используя свойства или нет) вы должны вызвать release в вашем dealloc.

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