Когда подходящее время выпустить объект? - PullRequest
1 голос
/ 29 января 2011

Я все еще немного запутался в этом.

Я создаю объект программно в XCode, скажем, UILabel, который также будет свойством класса.

Когда подходящее время для освобождения объекта, в методе, в котором он был создан, или в методе dealloc, как обычные объекты IBOutlet?

Спасибо.

Ответы [ 2 ]

3 голосов
/ 29 января 2011

Это зависит от того, настроено ли ваше свойство на сохранение значения или нет.Обычно вы хотите, чтобы средства доступа (генерируемые @synthesize) обрабатывали сохранение / освобождение, когда для свойства установлено новое значение.Вы указываете такое свойство, как это:

MyController.h

@interface MyController : UIViewController {
 UILabel *myLabel;
}

@property (nonatomic, retain) UILabel *myLabel;

@end

Затем вы можете использовать @synthesize для генерации получателей и установщиков по умолчанию.Установщик по умолчанию для свойства 'retain' освободит текущее значение и сохранит новое значение.Тем не менее, ничего не сделано для вас в dealloc.Это означает, что когда контроллер будет уничтожен, ваша ссылка на ваш ярлык будет утечка, так как выпуск не будет вызван.По этой причине вам необходимо освободить вызов для всех ваших свойств 'retain' в dealloc, например:

MyController.m

@implementation MyController

@synthesize myLabel;

-(void) dealloc {
 self.myLabel = nil;

 [super dealloc];
}

@end

Обратите внимание, что в этом случае, self.myLabel = nil почти эквивалентно вызову [myLabel release], поскольку установщик вызовет release для существующего значения, а затем вызовет retain для нового значения.Поскольку новое значение равно nil, вызов [nil retain] не имеет никакого эффекта.Я предпочитаю ноль вместо выпуска, так как вы также устанавливаете ivar в ноль и избегаете висячих указателей.

Когда вы создаете такое свойство программно, а не из Интерфейсного Разработчика, вам не нужно отмечать егос IBOutlet.В тех случаях, когда вы создаете элемент управления с использованием IB, вам следует обнулить все ссылки на IBOutlet в viewDidUnload.Это потому, что ваш контроль может быть освобожден вместе с представлением, если оно не было сохранено.Ссылка на него впоследствии приведет к сбою приложения, поэтому рекомендуется обнулять их, например:

- (void)viewDidUnload {
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;

    self.myIBLabel = nil;
}

Еще одна распространенная ошибка, которая возникает при использовании свойств, это пропуск части «self».Если вы не используете нотацию self.myIBLabel, вы пропускаете геттер и сеттер и напрямую работаете с иваром.Это НЕ сохранит / освободит объект.

2 голосов
/ 29 января 2011

Вы должны освободить его в методе dealloc, хотя это зависит от того, как вы создаете свойство класса.

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

Вот типичный пример:

- (void) someMethod {
    UILabel *myLabel = [[UILabel alloc] initWithFrame:myFrame];

    self.textLabel = myLabel;
    [myLabel release];
}


- (void) dealloc {
    [textLabel release];
}
...