Может ли кто-нибудь помочь мне с этой трассировкой стека в приложении для iPhone?
-
12-09-2019 - |
Вопрос
Program received signal: “EXC_BAD_ACCESS”.
(gdb) bt
#0 0x30011940 in objc_msgSend ()
#1 0x30235f24 in CFRelease ()
#2 0x308f497c in -[UIImage dealloc] ()
#3 0x30236b78 in -[NSObject release] ()
#4 0x30a002a0 in FlushNamedImage ()
#5 0x30250a26 in CFDictionaryApplyFunction ()
#6 0x30a001a4 in _UISharedImageFlushAll ()
#7 0x30a00738 in +[UIImage(UIImageInternal) _flushCacheOnMemoryWarning:] ()
#8 0x3054dc80 in _nsnote_callback ()
#9 0x3024ea58 in _CFXNotificationPostNotification ()
#10 0x3054b85a in -[NSNotificationCenter postNotificationName:object:userInfo:] ()
#11 0x3054dbc0 in -[NSNotificationCenter postNotificationName:object:] ()
#12 0x30a00710 in -[UIApplication _performMemoryWarning] ()
#13 0x30a006a8 in -[UIApplication _receivedMemoryNotification] ()
#14 0x30a005d8 in _memoryStatusChanged ()
#15 0x30217416 in __CFNotificationCenterDarwinCallBack ()
#16 0x3020d0b0 in __CFMachPortPerform ()
#17 0x30254a76 in CFRunLoopRunSpecific ()
#18 0x3025416a in CFRunLoopRunInMode ()
#19 0x320452a4 in GSEventRunModal ()
#20 0x308f037c in -[UIApplication _run] ()
#21 0x308eea94 in UIApplicationMain ()
#22 0x00002096 in main (argc=1, argv=0x2ffff514)
В настоящее время у меня есть очень странная ошибка в моей программе.Иногда это происходит, а иногда нет.Но вот краткое изложение того, что происходит:
Когда программа запустится:
- сохраненные данные (просто короткий список из 13 элементов) загружаются, если они существуют.
- огромный список, содержащий 1014 строк, загружается в NSMutableDictionary.
- другой plist, содержащий 78 строк, загружается в NSArray.
- воспроизводится фильм в формате .mp4.
Ошибка возникает в той части, где OpenGL ES View удаляется, и пользователь собирается просмотреть одну из строк из 1014 строк в NSMutableDictionary.
Эта ошибка никогда не возникает в симуляторе.Это происходит только на iPhone, и иногда он работает нормально, но иногда выходит из строя.
Однако, прочитав трассировку стека, я увидел там CFDictionaryApplyFunction, поэтому подумал, что это может быть одной из возможных причин.Не потому ли, что на симуляторе он читает настолько быстро, что весь словарь из списка загружается в одно мгновение, а на устройстве он читает медленнее?Честно говоря, я не знаю точно, как работает словарь.Считывает ли он все 1014 строк одновременно или использует какие-то другие потоки для медленного чтения?Пожалуйста посоветуй.Спасибо.
Решение
Когда вы получите EXC_BAD_ACCESS
, это часто означает, что вы пытаетесь вызвать метод объекта, которого нет — возможно, потому, что он был освобожден.
Примерно на середине трассы есть несколько предупреждение памяти звонки, например:
#12 0x30a00710 in -[UIApplication _performMemoryWarning] ()
Из-за этого создается впечатление, что ни один из ваших кодов не является напрямую вызывающий сбой, а скорее системное уведомление, когда памяти не хватает.
Ближе к кадру №0 кажется, что он пытается очистить кэш UIImage
объект, и это, по-видимому, плохой доступ.
Исходя из этого, можно предположить, что вы назначаете указатель на автоматически возвращаемое значение удобного конструктора;затем объект автоматически освобождается, и вы можете подумать, что все в порядке, потому что вы не используете изображение напрямую, но предупреждение памяти пытается получить к нему доступ.Например:
@interface MyClass {
UIImage* myImage;
}
// ...
- (id) init { /* the usual stuff */
myImage = [UIImage imageNamed:@"bob_the.png"];
return self;
}
В этом примере, даже если у вас настроено свойство сохранения на myImage
, вы на самом деле не сохраните изображение, если не установите значение через self.myImage
.Итак, вскоре после этого звонка изображение публикуется, и вы получаете указатель на нейтральную зону.
Не видя кода, я не могу узнать, происходит ли это на самом деле, но это один из типов ошибок, которые легко допустить.
Эти связанные вопросы дают советы по подобным сбоям: EXC_BAD_ACCESS
отладка Вопрос 1 и вопрос 2.
Наконец, если ничего из этого не поможет, я предлагаю найти минимальное воспроизводство вашей проблемы.Сложный способ сделать это — скопировать код, вырезать половину, посмотреть, сохраняется ли ошибка, и повторять, пока не получите наименьший код, который сможете найти, который воспроизводит ошибку.Обычно оттуда намного проще отлаживать (и более удобно публиковать это в качестве вопроса о stackoverflow!) Если вы знаете простой способ, дайте мне знать.
Другие советы
Возможно, вы захотите установить NSZombiesEnabled
переменная среды.Таким образом, ваше приложение не выйдет из строя с EXC_BAD_ACCESS
при доступе к выпущенным объектам, а записывает информативное сообщение на вашу консоль. Этот пост в блоге довольно хорошо объясняет, что происходит и как это настроить в XCode.В любом случае, НИКОГДА НИКОГДА не забывайте отключать эту опцию в производственных выпусках, поскольку в противном случае ваши объекты никогда не будут выпущены!