Пожалуйста, помогите: UINavigationController и управление памятью контроллеров просмотра

У меня странная проблема с вызовом метода при каждом нажатии кнопки:

- (void)launcherView:(TTLauncherView*)lnchr didSelectItem:(TTLauncherItem*)itm {
  MyObject* obj = ...

  MyViewController* detailView = [[MyViewController alloc] init];  // line A
  [self.navigationController pushViewController:detailView animated:YES];
  [detailView setObject:obj];
  detailView = nil;  // should I also release it? -- line B
}

Проблема в том, что я прошу прощения за то, что я должен освободить detailView (инструмент памяти показывает мне, что у меня есть утечка памяти, если это не сделано), также потому, что navigationController должен сохранить мой detailView, но и то, и другое, если я попытаюсь добавить autorelease в строке «A» или в строке «B» или просто выпуск для detailView в строке «B» (конечно, до присвоения ему значения nil), программа аварийно завершает работу с EXC_BAD_ACCESS, потому что сообщение о выпуске отправляется освобожденному экземпляру [CALayer]...

Есть идеи? Большое спасибо


person Dmitri Sologoubenko    schedule 24.03.2011    source источник


Ответы (4)


Это работает без сбоев?

- (void)launcherView:(TTLauncherView*)lnchr didSelectItem:(TTLauncherItem*)itm {
  MyObject* obj = ...

  MyViewController* detailView = [[MyViewController alloc] init];
  [self.navigationController pushViewController:detailView animated:YES];
  //[detailView setObject:obj];  // <- What's this for?
  [detailView release]
}
person Kirby Todd    schedule 24.03.2011
comment
[detailView setObject:obj]; устанавливает подписи меток представления MyViewController в соответствии со свойствами MyObject. Я узнал, что я должен отображать свое представление на основе NIB ПЕРЕД попыткой установить метки и т. Д., В противном случае мои свойства метки IBOutlet в контроллере будут найдены как нулевые методами setObject, и поэтому setObject станет бесполезным... Разве это не правда? ? - person Dmitri Sologoubenko; 25.03.2011
comment
Я сделал попытку, как вы предложили, и она НЕ падает... Таким образом, сбой, похоже, зависит от вызова [detailView setObject:obj]! Но я ДОЛЖЕН установить свойства моего IBOutlet ПОСЛЕ нажатия контроллера представления, иначе все IBOutlet будут нулевыми, не так ли? Моя текущая реализация setObject в MyViewController освобождает любой ранее сохраненный объект, затем сохраняет объект и затем соответствующим образом устанавливает свойства (заголовки) IBOutlet. А, obj — это ManagedObject из Core Data. - person Dmitri Sologoubenko; 25.03.2011
comment
МОЯ ОШИБКА, ИЗВИНИТЕ за потерю времени! :) Спасибо за ваш ответ: я обнаружил неправильное освобождение объекта в моем методе setObject. БОЛЬШОЕ СПАСИБО и еще раз извините. - person Dmitri Sologoubenko; 25.03.2011

попробуй так

- (void)launcherView:(TTLauncherView*)lnchr didSelectItem:(TTLauncherItem*)itm {
  MyObject* obj = ...

  MyViewController* detailView = [[MyViewController alloc] init]; 
  [detailView setObject:obj];
  [self.navigationController pushViewController:detailView animated:YES];
  [detailView release];
  detailView = nil;  // now this will be optional
}
person Vaibhav Tekam    schedule 24.03.2011
comment
Ни в коем случае, вылетает так же. Я также предпринял следующую попытку: преобразовал объект в свойство сохранения и реализовал новый метод refreshView, который принимает сохраненный экземпляр объекта и соответственно устанавливает метки detailView, затем перемещает вызов [detailView setObject:obj] перед pushView (как вы предложили) а затем вставил [detailView refreshView] сразу после вызова pushViewController, но сбой сохраняется. Я должен установить detailViews IBOutlets ПОСЛЕ pushViewController, потому что (прошу прощения из-за оптимизации использования памяти), если я вызову его до того, как они будут равны нулю! - person Dmitri Sologoubenko; 25.03.2011

попробуйте "initwithnibname"

не имеет отношения, но если вы преследуете утечки памяти, не забудьте освободить MyObject

person Bogdan S    schedule 24.03.2011
comment
Спасибо, MyObject сохранен/выпущен правильно: я просто опустил его, чтобы упростить пример кода :) - person Dmitri Sologoubenko; 25.03.2011
comment
Почему initWithNibName должен быть другим? - person Dmitri Sologoubenko; 25.03.2011

Когда вы устанавливаете detailView = nil;, не отпуская его, вы только обнуляете указатель на память. Блок памяти по-прежнему выделяется, пока вы его не освободите.

Вы должны использовать [detailView release] перед detailView = nil, иначе у вас не будет возможности снова сослаться на этот блок памяти (утечка памяти).

person Christopher Moore    schedule 24.03.2011
comment
Извините, как я уже сказал, я думаю, что должен выпустить его, чтобы избежать утечек памяти, но я пытался, и приложение вылетает с ошибкой EXC_BAD_ACCESS, потому что сообщение об освобождении отправлено на освобожденный экземпляр [CALayer], это настоящая проблема! - person Dmitri Sologoubenko; 25.03.2011