Подтвердить что ты не робот

Нужно ли освобождать ресурсы xib?

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

IBOutlet UILabel *lblExample;

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

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

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

Ответ 1

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

@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.

Однако одно соображение заключается в том, что ваш контроллер может распоряжаться своим пользовательским интерфейсом и динамически загружать его по требованию (например, если у вас есть контроллер представления, который загружает представление из файла nib, но по запросу - скажем, под давлением памяти - освобождает его, ожидая, что его можно перезагрузить, если снова потребуется просмотр). В этой ситуации вы хотите убедиться, что при удалении основного вида вы также откажетесь от владения любыми другими выходами, чтобы их тоже можно было освободить. Для 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];
}

Ответ 2

Я нашел то, что искал в документах 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

[anOutlet release], anOutlet = nil;

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

Ответ 6

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

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

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

@property (nonatomic, retain) UILabel *lblExample;

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

Ответ 7

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

Ответ 8

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