iOS: почему я должен освобождать сначала методы viewDidUnload, а затем методы dealloc? - PullRequest
1 голос
/ 12 мая 2011

Я нашел на страницах документации Apple пример, в котором они освобождают память следующим образом:

- (void)viewDidUnload
{
  self.mapAnnotations = nil;
  [super viewDidUnload];

  // Relinquish ownership of anything that can be recreated in viewDidLoad or on demand.
  // For example: self.myOutlet = nil;
}

- (void)dealloc
{
  [mapAnnotations release];
  [super dealloc];
}

Мне было интересно, почему

  1. сначала они устанавливают mapAnnotation в nil в viewDidUnload, а затем освобождают в методе dealloc и

  2. почему они ссылаются на mapAnnotation с и без self.

Кстати, это загружаемый пример: Пример MapCallouts

Ответы [ 3 ]

2 голосов
/ 12 мая 2011

viewDidUnload можно рассматривать как противоположность viewDidLoad. Он вызывается в случаях, когда представление выгружается из-за предупреждений памяти, но контроллер представления фактически не освобождается.

Позволяет освободить память, которая имеет отношение только к загрузке представления, и, следовательно, позволяет освободить память в этих условиях нехватки памяти.

Что касается разницы между двумя выпусками, один использует self, а другой нет:

В методе viewDidUnload переменная устанавливается на nil с помощью методов доступа. Переменная была объявлена ​​как свойство, вероятно, с атрибутом retain. При назначении nil через свойство, оно функционально совпадает со следующим кодом:

- (void)setMyObject:(MyObject *)object
{
    [myObject release];
    myObject = [object retain];
}

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

В методе dealloc доступ к переменной осуществляется напрямую, а не через метод доступа или свойство, и освобождается. На самом деле нет нужды назначать nil в этой точке, потому что объект-владелец будет освобожден и не будет иметь доступа ни к одному из его указателей, что делает возможность разыменования висящего указателя очень низкой.

2 голосов
/ 12 мая 2011

Вопрос, который вы должны задать: когда viewDidUnload вызывается?

Короче, он вызывается в ситуациях с нехваткой памяти, когда вы не хотите освобождать весь контроллер, т. Е. Когда вы не хотите, чтобы dealloc вызывали.

Вы можете думать о viewDidUnload как о противоположном viewDidLoad из loadView, тогда как dealloc - это противоположное init,(На практике это может быть немного сложнее, чем это, конечно.)

0 голосов
/ 12 мая 2011

(1) Это сделано для того, чтобы вы могли отпустить ссылки, чтобы система могла освободить ресурсы в ситуациях нехватки памяти.Он является обратной величиной viewDidLoad:

(2) Если вы ссылаетесь на себя с использованием точечной нотации, вы, возможно, создадите объект, который является деталью реализации свойства.Использование имени обеспечивает освобождение самого объекта, а не объекта, возвращаемого свойством.В первом примере, в случае розетки, присвоение nil с точечной нотацией (self.) Уменьшит счет сохранения оставшегося свойства.

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