2012-03-06 2 views
5

У меня есть следующий код:NSDictionary AllKeys сбои - не могут понять отчет аварии обстоятельства

- (Item *) getRandomItem { 
    if (itemIDs == nil) { 
     [self parse]; 
    } 
    NSArray * allKeys = [allItems allKeys]; 
    int seed = arc4random()%[allKeys count]; 
    return [self getItemByID:[allKeys objectAtIndex:seed]]; 
} 

Это иногда происходит сбой в прямом приложении, но мы не можем воспроизвести аварии. Я пытался проанализировать отчет и понять, что может быть причиной крушения, но я не добился успеха. В любом случае я пытаюсь вмешаться в объект allItems, чтобы вызвать сбой, приводит к другой ошибке, чем описанная здесь.

Я хотел бы получить некоторую помощь понимания при каких обстоятельствах следующих аварии будут происходить:

Hardware Model:  iPhone3,1 
Code Type:  ARM (Native) 
Parent Process: launchd [1] 
OS Version:  iPhone OS 5.0.1 (9A405) 
Report Version: 104 
Exception Type: EXC_BAD_ACCESS (SIGSEGV) 
Exception Codes: KERN_INVALID_ADDRESS at 0x00000010 
Crashed Thread: 0 

Thread 0 name: Dispatch queue: com.apple.main-thread 
Thread 0 Crashed: 
0 libobjc.A.dylib     0x3427eb30 _class_isInitialized 
1 libobjc.A.dylib     0x3427e8d6 _class_initialize 
2 libobjc.A.dylib     0x3427e88e prepareForMethodLookup 
3 libobjc.A.dylib     0x3427e76a lookUpMethod 
4 libobjc.A.dylib     0x3427e008 objc_msgSend_uncached 
5 CoreFoundation     0x33f7c020 CFRetain 
6 CoreFoundation     0x33f85bac +[__NSArrayI __new::] 
7 CoreFoundation     0x33f85ac6 -[__NSPlaceholderArray initWithObjects:count:] 
8 CoreFoundation     0x33f85806 +[NSArray arrayWithObjects:count:] 
9 CoreFoundation     0x33fa0e92 -[NSDictionary allKeys] 
10 AClockworkBrain     0x0008f46e -[ItemManager getRandomItem] (ItemManager.m:360) 
...... 

Спасибо.

+0

Вы используете ARC или нет? Это похоже на ошибку, связанную с памятью. –

+1

Подождите, вы пытаетесь добавить сырое целое в словарь? Вы пытаетесь отправить сообщение объекту в память 0x10, что похоже на то, что было бы нормальным целым числом в вашем приложении. –

+0

Ричард, мы не используем ARC. – dimitrios

ответ

9
Thread 0 name: Dispatch queue: com.apple.main-thread 
Thread 0 Crashed: 
0 libobjc.A.dylib     0x3427eb30 _class_isInitialized 
1 libobjc.A.dylib     0x3427e8d6 _class_initialize 
2 libobjc.A.dylib     0x3427e88e prepareForMethodLookup 
3 libobjc.A.dylib     0x3427e76a lookUpMethod 
4 libobjc.A.dylib     0x3427e008 objc_msgSend_uncached 
5 CoreFoundation     0x33f7c020 CFRetain 
6 CoreFoundation     0x33f85bac +[__NSArrayI __new::] 
7 CoreFoundation     0x33f85ac6 -[__NSPlaceholderArray initWithObjects:count:] 

Это крах подпись чрезмерно релиз или коррупции. В частности, один из ключей в вашем словаре был перевыполнен и/или поврежден. В частности, указатель isa теперь указывает на мусор.

Когда allKeys пытается создать временный массив всех ключей, он пытается сохранить поврежденный объект (через CFRetain, но относиться к нему как призыв к retain). Среда выполнения не распознает указатель isa как инициализированный класс (поскольку он указывает на мусор), и он пытается вызвать initialize в этом «классе», что приводит к сбою.

Теперь случается так, что поврежденный isa, вероятно, является значением, которое указывает на доступное для чтения, но мусорное меню, что приводит к сбою нескольких слоев в глубину во время выполнения. Чаще всего это происходит из-за того, что объект был перевыпущен, а затем какая-то структура оказалась malloc() 'd в том же месте, и эта структура имеет указатель как первую запись, которая является полностью общей структурой для структур.

Чтобы исправить?

Сначала запустите анализатор и устраните любые проблемы, с которыми он жалуется.

Далее, проверьте все виды использования объектов, которые являются ключами в этом словаре. Посмотрите, можете ли вы найти, где может произойти перевыпуск.

Наконец, попробуйте включить зомби и посмотреть, можете ли вы воспроизвести аварий.

+0

bbum спасибо за такой подробный ответ. У меня нет знания всей этой информации на низком уровне, но действительно кажется, что вы это делаете. Мы внимательно изучим это. Еще раз спасибо! – dimitrios

+1

Этот сбой произошел со мной, потому что я назвал '[myDict allKeys]' в другом потоке, чем тот, где управлялись объекты. Как говорится в этом ответе, это были указатели на освобожденные объекты. – stevel

-2

Помогите, если вы сделаете это?

NSArray * allKeys = [NSArray arrayWithArray:[allItems allKeys]]; 
+4

Зачем это помогло? – Chuck

+0

Это не помогло бы. – bbum

+0

Не должен был спешить. Я должен был добавить его в комментарий, мой плохой! –

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