Нужно ли выпускать в Deloc? - PullRequest
3 голосов
/ 01 марта 2010

В книге, которую я изучаю для iPhone dev, они используют IBOutlet экземпляры с помощью Interface Builder. Примером может быть UIButton. Таким образом, они добавляют в структуру что-то вроде этого:

 IBOutlet UIButton *whateverButton;

Затем они добавляют @property для каждого из них в .h и @synthesize в .m.

Затем они включают release в dealloc .m. Два вопроса:

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

Ответы [ 3 ]

5 голосов
/ 01 марта 2010

Нужен ли релиз? Не все свойства уже обработаны автоматически

Если собственность сохранена, освобождение необходимо. Когда вы объявляете @property и @synthesize, все, что вы получаете - это методы доступа, в dealloc нет специального автоматического поведения.

Кроме того, в IBOutlet нет ничего волшебного - это всего лишь маркер для Interface Builder, чтобы увидеть, какие свойства вы хотели бы видеть в IB. Это просто пустой макрос, Cmd-клик по ключевому слову IBOutlet, чтобы увидеть его определение:

#ifndef IBOutlet
#define IBOutlet
#endif

То же самое относится и к IBAction, который расширяется до void.

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

Когда мне нужно отладить управление памятью, я обычно просто устанавливаю точку останова в методе dealloc или записываю туда строку. Также полезно регистрировать retainCount объекта вокруг вызовов, которые могут сделать что-то подозрительное.


Может также помочь увидеть, как директива @synthesize создает методы доступа. Когда вы объявляете оставшиеся @property и просите компилятор @synthesize их, вы получаете что-то вроде этого:

@property(retain) NSString *foo;
@synthesize foo;

- (void) foo {
    return foo;
}

- (void) setFoo: (NSString*) newFoo {
    // Try to think what would happen if this condition wasn’t
    // here and somebody called [anObject setFoo:anObject.foo].
    if (newFoo == foo)
        return;
    [foo release];
    foo = [newFoo retain];
}

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

5 голосов
/ 01 марта 2010

Свойства не обрабатываются автоматически. Самое близкое к этому то, что синтезированные средства доступа правильно выполняют свои обязанности по управлению памятью. Но это только те средства доступа. Свойства - это просто способ объявления доступных «вещей» в вашем классе. Они не получают особого отношения после этого. Это не включает какую-то сборку мусора. Так что да, релиз необходим.

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

Вы должны прочитать правила управления памятью Apple для Cocoa . Это довольно просто, как только вы это освоите. Я бы не рекомендовал сначала читать другие руководства, потому что тонкие искажения могут привести вас на неверный путь (например, идея о том, что свойства будут освобождены для вас, вероятно, возникла из-за того, что кто-то неправильно исказил их работу).

3 голосов
/ 01 марта 2010

Нужен ли релиз? Не все свойства уже обработаны автоматически

Это зависит от того, как реализовано свойство. Если оно реализовано автоматически (@synthesize 'd), свойство сохранит свое значение в установщике и сбросит его, если будет установлено другое значение. Если вы только что попали в Obj-C и Cocoa, вам следует прочитать о соглашениях по управлению памятью. Я разместил пост в своем блоге о них, в других местах также есть множество ресурсов.

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

Вы можете проверить свойство NSObject retainCount. Информация об этом здесь . Для расширенных целей отладки существует флаг среды NSZombieEnabled, который заставит все сообщения о выпуске не уменьшать счетчик ссылок, а зарегистрировать ошибку при доступе к объекту, который обычно был бы освобожден.

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