ОС iOS 4.2 вызывает viewDidUnload зомби (нераспределенный класс)

У меня есть набор UIViewController, которые я складываю с помощью NavigationController. Когда я доберусь до последнего элемента этой стопки, я вызову popToRootViewController. Если я попытаюсь снова создать эту стопку (и да, я использую некоторую загрузку памяти в своих представлениях), система вызовет memoryWarning и viewDidUnload для одного из моих предыдущих объектов в стопке навигационного контроллера. Я знаю, что это нормально, я не могу контролировать, когда он будет генерировать предупреждения о памяти или вызывать viewDidUnload. Проблема в том, что по какой-то причине, когда он попадает туда, «я» уже нераспределено (NSZombie), поэтому я не могу установить для своих свойств значение nil и освободить память. Если я это сделаю, я получу сообщение, отправленное на освобожденный экземпляр.

Две вещи:

(a) Есть ли способ принудительно освободить все подпредставления от навигационного контроллера, когда я использую root, чтобы я мог быть более «дружественным к памяти»?

(b) Зачем ему вызывать viewDidUnload нераспределенного класса?

Вот трассировка стека, которую я получаю:

#0  0x33a69910 in ___forwarding___ ()
#1  0x33a69860 in __forwarding_prep_0___ ()
#2  0x0000e4a2 in -[MyViewController viewDidUnload] at /Users/Fernando/src/Classes/MyViewController.m:866
#3  0x32105484 in -[UIViewController unloadViewForced:] ()
#4  0x321053d0 in -[UIViewController unloadViewIfReloadable] ()
#5  0x3219ede4 in -[UIViewController purgeMemoryForReason:] ()
#6  0x3219ee04 in -[UIViewController didReceiveMemoryWarning] ()
#7  0x0000e426 in -[MyViewController didReceiveMemoryWarning] ()
#8  0x3219ee1a in -[UIViewController _didReceiveMemoryWarning:] ()
#9  0x3362d622 in _nsnote_callback ()
#10 0x33a47122 in __CFXNotificationPost_old ()
#11 0x33a46dc2 in _CFXNotificationPostNotification ()
#12 0x3361cd22 in -[NSNotificationCenter postNotificationName:object:userInfo:] ()
#13 0x33626240 in -[NSNotificationCenter postNotificationName:object:] ()
#14 0x32167da8 in -[UIApplication _performMemoryWarning] ()
#15 0x321689ca in -[UIApplication _receivedMemoryNotification] ()
#16 0x32165776 in _memoryStatusChanged ()
#17 0x33a770cc in __CFNotificationCenterDarwinCallBack ()
#18 0x33a5dbe6 in __CFMachPortPerform ()
#19 0x33a556fe in __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ ()
#20 0x33a556c2 in __CFRunLoopDoSource1 ()
#21 0x33a47f7c in __CFRunLoopRun ()
#22 0x33a47c86 in CFRunLoopRunSpecific ()
#23 0x33a47b8e in CFRunLoopRunInMode ()
#24 0x33b0e4aa in GSEventRunModal ()
#25 0x33b0e556 in GSEventRun ()
#26 0x32099328 in -[UIApplication _run] ()
#27 0x32096e92 in UIApplicationMain ()
#28 0x00002c72 in main at /Users/Fernando/src/main.m:13

Любая помощь/предложение очень ценится!

Спасибо,

Фернандо


person cusquinho    schedule 28.02.2011    source источник


Ответы (1)


(a) Есть ли способ принудительно освободить все подпредставления от навигационного контроллера, когда я использую root, чтобы я мог быть более «дружественным к памяти»?

Может быть, вы можете получить возвращаемое значение popToRootViewController и отпустить их?

(b) Зачем ему вызывать viewDidUnload нераспределенного класса?

Не уверен, можете ли вы поделиться своим кодом, если это возможно?

person Vijay Kiran    schedule 01.03.2011
comment
Спасибо за быстрый ответ. Я попытаюсь работать с результатами popToRootViewController, чтобы быть более удобным для памяти, и поделюсь кодом, если он работает. Что касается пункта б, я нашел, почему. Я отписывался от списка делегатов в viewDidUnload(), и это вызывало Dealloc и возвращалось к viewdidunload с классом как Zombie. Думаю, viewdidunload — не лучшее место для отказа от подписки на список делегатов... Еще раз спасибо! - person cusquinho; 01.03.2011
comment
Благодарим вас за размещение вашего пункта b результат! Я потратил больше часов, чем осмелюсь признать, на точно такую ​​же проблему. Я удалял обратный вызов в методе viewDidUnload, который, в свою очередь, вызывал Dealloc, и когда он возвращался к viewDidUnload, это был зомби. Решение состояло в том, чтобы переместить удаление обратного вызова в метод viewWillDisappear. - person sradforth; 22.05.2012