Может кто-нибудь помочь мне с этой трассировкой стека в приложении для iPhone? - PullRequest
0 голосов
/ 08 августа 2009
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.
  • другой список, содержащий 78 строк, загружается в NSArray.
  • .mp4 фильм воспроизводится.

Ошибка возникает в части, где OpenGL ES View удаляется, и пользователь собирается просмотреть одну из строк из 1014 строк в NSMutableDictionary.

Эта ошибка никогда не возникает в симуляторе. Это происходит только на iPhone, иногда работает нормально, но иногда ломается.

Однако, прочитав трассировку стека, я увидел там CFDictionaryApplyFunction, поэтому я подумал, что это может быть одной из возможных причин. Это потому, что на симуляторе он читает вещи так быстро, что весь словарь из списка загружается мгновенно, а на устройстве - медленнее? Честно говоря, я не знаю точно, как работает словарь. Читает ли он все 1014 строк в одно мгновение или использует другие потоки для медленного чтения? Пожалуйста посоветуй. Спасибо.

Ответы [ 2 ]

5 голосов
/ 08 августа 2009

Когда вы получаете 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 .

Наконец, если ничего из этого не поможет, я предлагаю найти минимальное воспроизведение вашей проблемы. Трудный способ сделать это - скопировать ваш код, вырезать половину, посмотреть, все ли еще есть ошибки, и повторять до тех пор, пока вы не получите наименьший найденный код, который воспроизводит ошибку. Оттуда обычно гораздо проще отлаживать (и, кроме того, более выносливый вопрос о переполнении стека!) Если вы знаете простой способ, дайте мне знать.

1 голос
/ 08 августа 2009

Вы можете установить переменную окружения NSZombiesEnabled. Таким образом, ваше приложение не будет аварийно завершать работу с EXC_BAD_ACCESS при доступе к освобожденным объектам, а скорее записывает информативное сообщение на вашу консоль. Это сообщение в блоге довольно хорошо объясняет, что происходит и как настроить его в XCode. В любом случае, НИКОГДА не забывайте отключать эту опцию в производственных выпусках, так как иначе ваши объекты никогда не будут выпущены!

...