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

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

IBOutlet UILabel *lblExample;

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

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

-(void)dealloc{
    [lblExample release];//?????????
}
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
37
0
9 261
8
Перейти к ответу Данный вопрос помечен как решенный

Ответы 8

Связанный: Понимание подсчета ссылок с помощью Cocoa / Objective C

@Soeren: Я уже прочитал эту статью и понял ее содержание. Мой вопрос касался объектов, созданных на IB xib, которые он не охватывает. Например: на самом деле я никогда не создаю и не присваиваю ярлык, все это делает магия IB. Итак, что мне нужно знать, очень просто: нужно ли мне его выпустить?

rustyshelf 15.09.2008 08:09

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

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

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

@property (nonatomic, retain) UILabel *lblExample;

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

Это не так. Если вы не используете свойства (или реализуете свои собственные методы доступа), то, следует ли вам выпускать, зависит от того, на какой платформе вы находитесь и каков ваш суперкласс. Например, если вы наследуете от NSWindowController, вы не освобождаете.

mmalc 11.10.2008 13:50

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

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

На самом деле это неправильно. Следует ли вам отправлять объектам верхнего уровня сообщение о выпуске, зависит от того, какую платформу вы используете и от какого класса наследуется ваш владелец файла. Например, если он наследуется от NSWindowController, вам не нужно их освобождать.

mmalc 10.10.2008 19:43
Ответ принят как подходящий

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

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


@implementation MyController

@synthesize uiElement;

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

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

Примечание. Следующие комментарии относятся только к 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];
}

Если у нас есть свойство сохранения, нельзя ли упростить его, просто сказав self.uiElement = nil; во всех местах, которые мы хотим освободить, поскольку это свойство сохранения, оно должно фактически освободить его должным образом, а также без проблем установить для него значение nil - одно из преимуществ сохранения свойств.

user3023451 24.11.2010 16:44

Обычно вы делаете self.uiElement = nil; в viewDidUnload, но не в setView:. И было бы понятнее просто вызвать self.anOutlet = nil; в dealloc.

Jesse Rusak 15.01.2011 17:38

Вы не должны вызывать self.anOutlet = nil; в освобождении. Вызывать методы доступа в dealloc - плохая практика.

tobyc 01.02.2011 04:46

Я полностью не согласен с тем, что «вызывать методы доступа в dealloc - плохая практика». Я делаю это постоянно, это делает код в миллиард раз чище. У вас есть ссылка на это?

Wil Shipley 18.03.2011 21:35

@Wil Shipley: Некоторые документы Apple не рекомендуют использовать аксессоры в методах init и dealloc. Например: developer.apple.com/library/mac/#documentation/Cocoa/Concept‌ ual /… - AFAICT, в основном сеттеры могут (и в KVO имеют) иметь побочные эффекты, помимо простой установки переменной, и если вы запускаете уведомления KVO, вы можете в конечном итоге сказать людям, чтобы они отправляли сообщения объекта после его освобождения.

Chuck 03.04.2011 10:34

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

Oscar 29.02.2012 08:39

В

[anOutlet release], anOutlet = nil;

Часть будет совершенно излишней, если вы правильно написали setView :.

На самом деле, насколько я понимаю, это изменилось в версии 3.0 и более поздних версиях. Теперь у нас есть -viewDidUnload, и именно здесь мы выпускаем аксессоры.

Wil Shipley 18.03.2011 21:34

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

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

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

Другие вопросы по теме