iPhone dealloc и viewDidUnload Проблема - PullRequest
1 голос
/ 26 марта 2012

У меня быстрый вопрос о методах dealloc () и viewDidUnload (). Я замечаю много примеров кода, люди, кажется, делают разные вещи.

Кроме того, я мог бы добавить, что ARC не вариант.

(1) Должен ли я установить все свойства равными nil в методе dealloc (), включая IBOutlets. Например, я должен освободить переменную экземпляра [_myArrary release], а также установить self.myArrary = nil.

(2) В viewDidUnload, я думаю, я должен установить все IBOutlets на nil, а также все, что создано в viewDidLoad. Однако, что касается myString, допустим, что он инициализирован в другом методе после вызова viewDidLoad. Должен ли я установить это на ноль?

Если у меня есть некоторые свойства, объявленные как таковые:

@property (nonatomic, retain) IBOutlet UITableViewCell *myTableCell;
@property (nonatomic, retain) IBOutlet UILabel *myLabel;
@property (nonatomic, retain) NSArray *myArrary;
@property (nonatomic, retain) NSString *myString;

I synthesize them as such:

@synthesize myArrary = _myArrary;
@synthesize myTableCell;
@synthesize myLabel;
@synthesize myString;

- (void)viewDidLoad
{
    [super viewDidLoad];

    _myArrary = [NSArrary alloc] initWithObjects:@"testObject", nil];
}

- (void)viewDidUnload
{
    self.myArrary = nil;

    self.myTableCell = nil;

    self.myLabel = nil;

    [super viewDidUnload];
}

- (void)dealloc
{   
    [_myArray release];

    [super dealloc];
}

Ответы [ 2 ]

4 голосов
/ 26 марта 2012
  1. Не имеет значения, если вы установите свойства / переменные равными nil в dealloc, потому что как только объект будет освобожден, вы все равно не сможете получить к ним доступ.При сохранении свойств выполнение

    self.varname = nil;

    освободит переменную и установит ее в ноль.Многие люди предпочитают только освобождать их, я предпочитаю установить для свойств сохранения значение nil для согласованности.

  2. В viewDidUnload вы должны освободить и установить на nil все, что не нужно и что будетвоссоздается, когда представление загружается снова.Это не строгое правило, но хорошая практика - держать как можно больше доступной памяти.Если ваша строка будет воссоздана в viewDidLoad, и вам не нужно будет обращаться к ней до тех пор, пока представление не будет загружено снова, вам, вероятно, следует освободить ее (и я бы для безопасности установил ее на ноль).

    Еще одно примечаниеviewDidUnload не всегда вызывается перед dealloc.Таким образом, вы должны освобождать каждое свойство / переменную dealloc, даже если оно также освобождено и имеет значение nil в viewDidUnload.Чтобы убедиться, что вы не утечете, когда ваш класс освобожден, ваша функция dealloc для этого кода должна выглядеть следующим образом:

    - (void)dealloc {
        [myTableCell release];
        [myLabel release];
        [_myArray release];
        [myString release];
    
        [super dealloc];
    }
    

    Установка их в ноль также допустима, но только если вы используетесинтезированный сеттер, потому что это также освобождает переменную.

    self.myLabel =  nil;
    

    в порядке, но

    myLabel = nil;
    

    имеет утечку.

2 голосов
/ 26 марта 2012

Как правило, вы хотите, чтобы ваш viewDidUnload освободил все, что может быть воссоздано в viewDidLoad, если ваш ViewController не был освобожден за это время.

В dealloc вам необходимовыпустить что-нибудь, что все еще принадлежит ViewController.Вы не можете предполагать, что viewDidUnload был вызван первым, поэтому будьте осторожны.

Помните также, что отправка сообщений на nil не принесет никакого вреда, но есть много вреда от отправки релиза объектам, которые вам не принадлежатили отправив его более одного раза на принадлежащие вам объекты.

Поскольку ваши свойства синтезированы, сохраните, вы можете избежать необходимости отправлять release самостоятельно и просто использовать установщик, чтобы установить для них значение nil (self.property = nil), при условии, конечно, что вы нигде не добавляли никаких дополнительных сохранений.

NB В вашем viewDidLoad вы явно назначили вновь созданный объект для iVar, который синтезировал ваше свойство.Не делай этого! Если другой объект установил свойство между созданием экземпляра и представлением, то он утечет .Используйте _ivar только тогда, когда вы точно знаете, что это правильно, и вы позаботились о каждом крайнем случае.

TL: DR - используйте self.property = nil в обоих viewDidUnloadи dealloc и никогда не назначайте новый объект для _ivar, если вы сначала не проверили, что он уже nil или не готовы освободить предыдущее значение.

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