2009-07-29 2 views
6

У меня проблема с сохранением/выпуском. Мой вид довольно сложный, поэтому я установил NSZombieEnabled в YES, и я пытаюсь найти, что именно объект вызывает у меня горе. Чтобы ускорить этот процесс, мне интересно, есть ли намеки или приемы для отслеживания зомби назад к могиле, из которой они выкапывали свой путь (извините, пришлось) или обратно к объекту, с которым они связаны? Сообщение с загадочным консольным сообщением, похоже, не дает большого понимания:NSZombies едят мозг моего приложения!

NSInvocation: warning: object 0x1076850 of class '_NSZombie_CALayer' does not implement methodSignatureForSelector: -- trouble ahead 

У меня нет селекторов, называемых «проблема впереди».

Edit - в том числе трассировку стека:

#0 0x3026e017 in ___forwarding___ 
#1 0x3024a0a2 in __forwarding_prep_0___ 
#2 0x302042e8 in CFRelease 
#3 0x00c4fc31 in CALayerUpdateSublayers 
#4 0x00c4e173 in -[CALayer dealloc] 
#5 0x00c4000e in CALayerRelease 
#6 0x00c48dad in CALayerFreeTransaction 
#7 0x00c410b8 in CA::Transaction::commit 
#8 0x00c492e0 in CA::Transaction::observer_callback 
#9 0x30245c32 in __CFRunLoopDoObservers 
#10 0x3024503f in CFRunLoopRunSpecific 
#11 0x30244628 in CFRunLoopRunInMode 
#12 0x32044c31 in GSEventRunModal 
#13 0x32044cf6 in GSEventRun 
#14 0x309021ee in UIApplicationMain 
#15 0x00001eb4 in main at main.m:14 

Edit 2: ObjectAlloc

Глядя адреса памяти в вопросе в ObjectAlloc я нахожу два матча:

# Address  Category   Creation Time  Size Responsible Library Responsible Caller 
0 0x1076980 GeneralBlock-48 00:11.470  48  QuartzCore -[CALayer setDelegate:] 
1 0x1076980 CALayer   00:11.552  48  UIKit  -[UIView _createLayerWithFrame:] 

копаться в # 0 GeneralBlock-48:

# Category  Event Type Timestamp Address Size Responsible Library Responsible Caller 
0 GeneralBlock-48 Malloc  00:11.470 0x1076980 48 QuartzCore -[CALayer setDelegate:] 
1 GeneralBlock-48 Free  00:11.551 0x1076980 -48 QuartzCore -[CALayer addAnimation:forKey:] 
2 CALayer   Malloc  00:11.552 0x1076980 48 UIKit -[UIView _createLayerWithFrame:] 

Копаем # 1 CALayer:

# Category  Event Type Timestamp Address Size Responsible Library Responsible Caller 
0 GeneralBlock-48 Malloc  00:11.470 0x1076980 48 QuartzCore -[CALayer setDelegate:] 
1 GeneralBlock-48 Free  00:11.551 0x1076980 -48 QuartzCore -[CALayer addAnimation:forKey:] 
2 CALayer   Malloc  00:11.552 0x1076980 48 UIKit -[UIView _createLayerWithFrame:] 

Ну, теперь я вижу, что бурение глубже в любом # 0 или # 1 показывает ту же самую информацию. Я полагаю, что это должно было сократить устранение неполадок этого пополам ... но я все еще не в порядке ...

+1

Вы пробовали программировать дробовики в своем приложении? – Sneakyness

+1

Я взял ярлык, попробовал деревянный кол ... увы, это работает только на NSVampires :-( – Meltemi

+0

+1 для деталей вопроса, и интересное название: D –

ответ

6

Я считаю, что обратная линия - это точка, в которой зомби пересылаются. Эта обратная трасса обычно дает вам нулевую информацию о том, что вызывает крушение. Это в значительной степени только говорит вам тип и адрес объекта, который перевыполнен.

Техника, которую я часто использую, чтобы отслеживать перевыпуски, как это, следует использовать ObjectAlloc для отслеживания всех сохранений и выпусков. Найдите адрес для расширенного объекта в ObjectAlloc, затем перечислите все вызовы сохранения/освобождения, а затем попытайтесь сбалансировать каждое сохранение с помощью выпуска. Как только вы найдете выпуск без сохранения для соответствия, вы нашли проблему.

+0

Извините, но как вы «перечислите все вызовы сохранения/освобождения» в «Инструменты»? – Meltemi

+1

В представлении таблицы, показывающем все распределения, щелкните стрелку рядом со значком «* All Allocations *». Найдите адрес зомби CALayer (вы можете вставить его в поле поиска ниже). Нажмите на стрелку рядом с этим адресом. На этом адресе вы увидите список всех вызовов malloc/free/keep/release. Откройте боковую панель, чтобы увидеть трассировку стека для каждого вызова. – kperryua

+0

Спасибо! Полезно! Но когда я запускаю ObjectAlloc, NSZombies не отображаются. Поэтому я не могу сравнить этот адрес с тем, что в списке. Я считаю, что инструменты обходят Отладчик, а также консоль XCode. Ах, я думаю, что я просто ответил на эту часть вопроса: посмотрите в Console.app, а не на консоли XCode ... – Meltemi

2

Одним быстрым шагом вы можете установить символическую точку останова на objc_exception_throw. Это заставит вашу программу приостанавливаться всякий раз, когда генерируется исключение. Это может не помочь вам отследить точно, который CALayer дает вам печаль, но это должно помочь вам найти общую окрестность, где его зовут.

+0

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

+0

У меня была точка останова objc_exception_throw, но для меня это было так же загадочно. Я разместил его выше. – Meltemi

+0

В чем смысл этой ошибки? Что вы делаете с вашей программой, чтобы она срабатывала? Из трассировки стека, похоже, что это происходит в конце транзакции CA, а это означает, что это безопасная ставка, что это происходит в конце анимации. Есть ли анимация? Если да, то какие слои задействованы? Уверены ли вы «сохранить», которые собираетесь использовать снова? – Alex

2

«Проблема впереди» является частью предупреждения, а не селектора. Само предупреждение возникает из NSInvocation, но тот факт, что он упоминает «class _NSZombie_CALayer», означает, что что-то пытается работать с CALayer, который был отменен.

Трассировка стека указывает, что это происходит, когда слой пытается выпустить свои подслои.

В целом, это означает, что освобождаемый слой имеет подуровень, который был перепутан где-то в вашем коде. Проверьте управление памятью CALayers или попробуйте Clang Static Analyzer.

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