2012-05-03 4 views
2

Один из моих UIViewController имеет несколько контроллеров детского вида. Они встроены в построитель интерфейсов, перетащив NSObject в раздел «Объекты» слева, а затем введите в свой собственный SpecialViewController «Пользовательский класс». С помощью этой настройки, после viewDidLoad, я получу свои взгляды и контроллер. Рабочий процесс предлагается следующим скриншотом:Правильно ручка didReceiveMemoryWarning

Drag "Object" to create instance

И в моей реализации, у меня есть:

@interface ParentController : UIViewController 
{ 
    SpecialViewController *svc; 
} 
@property (nonatomic, retain) IBOutlet SpecialViewController *svc; 

Как я понимаю, что во время didReceiveMemoryWarning я должен выпустить свои собственные ресурсы. Затем установите IBOutlets на нуль во время viewDidUnload.

Я получаю сбой при моделировании мало памяти в имитаторе, с отладчиком задержавшись на didReceiveMemoryWarning из SpecialViewController (чье тело просто [super didReceiveMemoryWarning];), с ошибкой EXC_BAD_ACCESS (code=1, address=0xe0000008). В это время родительский контроллер не отображается, поэтому его можно безопасно освободить.

Родительский контроллер также содержит только [super didReceiveMemoryWarning]; в didReceiveMemoryWarning. Я пробовал niling IBOutlets в обоих классах. Это не помогло.

Любая идея, почему это произошло?

Я ориентируюсь на iOS 4 & 5 с ARC. SpecialViewController является подклассом UITableViewController.

Через отслеживание, я обнаружил, что ParentController didReceiveMemoryWarning вызывается до SpecialViewController.

+1

Объект деблокирования и заданный объект равны нулю. Если вы уберете память, вы должны освободить ** неиспользуемые ** ресурсы. Сначала попробуйте '[svc release]'. – Feo

+1

@Feo, Хм ... Я использую ARC. Я освободил неиспользуемые ресурсы. Это те, которыми я управляю в своих классах, правильно? –

+0

Вы делаете 'self.scv = nil'? – Peres

ответ

2

Кажется, у вас есть контроллер вида с контроллером вида. Есть ли какая-то особая причина, которую вы выбрали для создания такого класса? По моему опыту каждый UIViewController должен быть отдельным подклассом. Исходя из того, что ваша ошибка возникает в didReceiveMemoryWarning, я считаю, что проблема в другом месте. Можете ли вы поделиться своим кодом инициализации для этого контроллера просмотра?

Если вы пытаетесь что-то вроде UIViewController Containment, вероятно, вы должны проверить тему WWDC, которая охватывает этот процесс.

+0

Я не знаю, что это странный подход. Метод '' initWithNibName' ничего не делает, кроме вызова super. Я помню, что видел этот метод где-то, но сейчас не могу получить ссылку. Он разработан таким образом, потому что пользовательский интерфейс имеет 3 разных вида таблицы, хотя они не отображаются одновременно. Плохой дизайн? –

+0

Да, очень плохой дизайн. Как насчет 3 UITableViews, содержащихся в 1 UIViewController. Программно переключить свойство 'hidden' на 2 из 3 UITableViews, чтобы показать правильный. – Sam

+0

Вы имеете в виду, что я должен сделать это, не инициируя 3 '' UITableViewControllers''? Просто управляйте ими отдельно через своих собственных делегатов? Ах, я просто понял. Я не должен использовать дополнительные контроллеры. Мне просто нужны делегаты. Спасибо. Я пересмотрю свой код и, надеюсь, вскоре приму ваш ответ. –

2

Просмотреть реализацию контроллера didReceiveMemoryWarning контроллера будет высвобождаться их представление; ваша ответственность заключается только в том, чтобы выпустить любые другие виды, созданные в viewDidLoad или loadView, а также любые сильные ссылки на подпрограммы IBOutlet.

У вас есть сильная ссылка на другой контроллер вида, который не будет воссоздавать, когда вид становится видимым снова. Вы должны не использовать didReceiveMemoryWarning, чтобы освободить переменную экземпляра sec; вместо этого полагайтесь на реализацию SpecialViewControllerdidReceiveMemoryWarning, чтобы позаботиться о выпуске его просмотра.

На практике я использую didReceiveMemoryWarning выпустить свой основной вид (self.view) и использовать viewDidUnload выпустить что-либо созданный в viewDidLoad. Я нахожу баланс имен методов и их использования интуитивным. Если вы создаете что-то в viewDidLoad, отпустите его в viewDidUnload.

+0

На самом деле, он падает таким же образом, если я не нолю '' IBOutlets''. Я думаю, что процесс niling существует только для защиты моего собственного кода. Теоретически не нужно, правильно? Но я хочу сказать, что контроллеры встроены в .xib. Я не создаю их в '' viewDidLoad''. –

+0

Они выведены так, что вы освободите как можно больше памяти (установка в nil выпускает любой предыдущий экземпляр).Поскольку вы ориентируетесь на iOS 4, у вас нет обнуления слабых ссылок, поэтому вполне вероятно, что переменная будет выпущена без указания ссылки на nil. Вы уверены, что вы не выпускаете 'svc' в контроллере представления? И вы используете «NSNotificationCenter» где угодно? Я видел, что это вызывает проблемы, а также в iOS 4. –

+0

В ARC plus объект создан в .xib, я не думаю, что могу его отпустить. Я не могу назвать выпуск. Но, как я уже сказал, это то же самое, независимо от того, было ли оно никем или нет. Ничего не происходит в '' didReceiveMemoryWarning''. Он еще не дошел до '' viewDidUnload''. –

Смежные вопросы