Авто-релиз против релиза в dealloc - PullRequest
7 голосов
/ 03 сентября 2011

Я знаю, что управление памятью в iOS является сложной задачей для таких новичков, как я, но я надеялся получить четкое объяснение здесь по поводу переполнения стека, которое я не смог найти где-либо еще.

Итак, представьте, что у меня есть свойство / ivar

@property(nonatomic, retain) UIPopoverController *popOver;

, которое я выделяю следующим образом:

self.popOver = [[[UIPopoverController alloc] initWithContentViewController:popOverContent] autorelease];    

Теперь в моих методах dealloc и viewDidUnload,Я делаю оба

// in viewDidUnload:
self.popOver = nil;
// in dealloc:
[popOver release];

Вопрос:

  1. Если я делаю nil / release в viewDidUnload / dealloc, действительно ли мне нужно автоматически выпускать при выделении?
  2. Viceнаоборот, если я делаю авто-релиз при распределении, нужно ли мне ноль / выпуск позже?
  3. Какая разница, если есть?

Заранее спасибо за ваше время - я будупродолжайте читать, серьезно, управление памятью не может быть таким сложным, чтобы обернуть голову ...

Ответы [ 3 ]

5 голосов
/ 03 сентября 2011

Не запутайтесь в автоматическом выпуске в этой строке:

self.popOver = [[[UIPopoverController alloc] initWithContentViewController:popOverContent] autorelease];

После этого утверждения вы фактически владеете объектом , потому что установщик свойств претендовал на владение им.Авто-релиз уравновешивает alloc-init.

Так что ... да, вам нужно автоматически выпустить при распределении.Если бы вы сделали это (без автоматического выпуска), вы бы пропустили:

self.popOver = [[UIPopoverController alloc] initWithContentViewController:popOverContent];

Другой вариант - использовать временную переменную вместо autorelease:

UIPopoverController *temp = [[UIPopoverController alloc] initWithContentViewController:popOverContent];
self.popOver = temp;
[temp release];

В любом случае вам нужноотпустите объект в dealloc.

5 голосов
/ 03 сентября 2011

1 Если я делаю nil / release в viewDidUnload / dealloc, действительно ли мне нужно автоматически выпускать при выделении?

Да.

2 И наоборот, если я делаю авто-релиз при выделении, нужно ли позже обнулять / освобождать?

Да.

В первом случае автоматическое освобождение выполняется от имени этого метода . Этот метод больше не нуждается в поповере, поэтому он должен (автоматически) его освободить.

На dealloc ваш объект больше не нуждается в поповере. Поэтому вам нужно освободить его.

Это очень просто. Вам не нужно учитывать долгосрочное владение объектом; Вам просто нужно думать очень локально, на уровне каждого метода. Решение освободить его или нет вовсе не зависит от того, хранится ли этот объект в некоторых других частях программы. В методе, если вы выделяете объект и он вам больше не нужен , в этом методе вы (автоматически) освобождаете его.

dealloc - небольшое исключение из правила. Там вам нужно освободить владельца всех переменных экземпляра.

Вот и все!

1 голос
/ 03 сентября 2011
  1. Да. Но, возможно, не в этом случае.
  2. Да. Но, может быть, не в этом случае.
  3. viewDidUnload вызывается, когда представление выгружается, dealloc вызывается, когда разрушается контроллер представления.

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

В dealloc вы очищаете viewController и здесь вы очищаете все его ресурсы, включая те, которые он назначил представлению.

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

...