недопонимание управления памятью указателя с целью - PullRequest
2 голосов
/ 25 июля 2009

Я использую iPhone SDK 3.0, но я думаю, что это общее недопонимание того, как все работает с управлением и памятью.

Я переопределил метод viewWillAppear, как этот

@implementation MyViewController
- (void)viewWillAppear:(BOOL)animated {
  NSArray *items = [NSArray arrayWithOjbects:self.searchButton, self.trashCan, nil];
  [self.bottomBar setItems:items animated:YES];
}
// other stuff...
@end

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

НО, я склонен «отпустить» исходный указатель на «элементы», потому что я думаю, ссылка на NSArray теперь поддерживается bottomBar. Но когда я делаю это (см. Код ниже) и пытаюсь переключиться с UIViewController, я получаю ошибку управления памятью (- [CFArray count]: сообщение отправлено на освобожденный экземпляр 0xd5f530).

- (void)viewWillAppear:(BOOL)animated {
  NSArray *items = [NSArray arrayWithOjbects:self.searchButton, self.trashCan, nil];
  [self.bottomBar setItems:items animated:YES];
  [items release];
} 

DoМне нужно , а не выпустить вещи в этом случае? Или я что-то не так делаю? Очевидно, эмпирические данные указывают на то, что я не должен выпускать «предметы», но мне непонятно, почему это так.

Спасибо за любую информацию / «указатели»!

Ответы [ 4 ]

3 голосов
/ 25 июля 2009

Вам не нужно выпускать его, потому что вы никогда его не инициировали. [NSArray arrayWithObjects:...] возвращает автоматически освобожденный объект. Вы не несете ответственности за его освобождение, потому что на него было отправлено сообщение об автозапуске, когда он вернулся из метода. Вам нужно только выпустить то, что вы инициализируете! (Если бы вы использовали [[NSArray alloc] initWithObjects:...], вам бы пришлось.)

0 голосов
/ 26 июля 2009

Ради всего святого, просто укажите людям на Правила управления памятью . Не перефразируйте их. Не говорите «возвращает автоматически освобожденный объект» (что не обязательно верно и не имеет отношения к реальности, даже если это правда). Просто укажите на них правила.

Правила - это всего 9 абзацев! Нет необходимости перефразировать их, отрицать их или переформулировать. Они ясны, кратки и явны.

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

0 голосов
/ 25 июля 2009

Вот краткая версия:

+ [NSArray arrayWithObjects:] возвращает объект, который вам не принадлежит, поэтому нет, вы не должны освобождать его.

С другой стороны, есливы сделали:

NSArray *items = [[NSArray alloc] initWithObjects:self.searchButton, self.trashCan, nil];

это создаст объект с счетом сохранения 1, поэтому вам нужно будет разблокировать его, чтобы предотвратить утечку.

Проверьте ПамятьРуководство по программированию управления для какао для более подробной информации.

0 голосов
/ 25 июля 2009

Когда вы вызываете arrayWithObjects: на NSArray:

NSArray *items = [NSArray arrayWithObjects:self.searchButton, self.trashCan, nil];

Вам возвращается автоматически выпущенный массив. Массив возвращается вам автоматически освобожденным, потому что вы не вызываете alloc, new или метод, содержащий copy. Это означает, что вам не нужно управлять этим объектом в памяти. (Для получения дополнительной информации см. Руководство по программированию управления памятью для какао )

Однако оно сохраняется при вызове setItems на self.bottomBar, передавая массив какаргумент, увеличивая его счетчик хранения до 1, но затем вы сбрасываете его, возвращая его счетчик хранения обратно в ноль, что приводит к его освобождению.

Поскольку массив сохраняется self.bottomBar, это означает, чтоэто управление памятью массива. Когда он больше не нужен, массив будет освобожден, подразумевая, что классу больше не нужен массив, что является правильным способом управления памятью.

...