我有以下代码:
- (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 :(得分: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()在同一位置,并且该结构碰巧有一个指针作为第一个条目,这是一个完全常见的结构模式。
要解决?
首先,运行分析器并修复它抱怨的任何问题。
接下来,检查该字典中键的对象的所有用法。看看你是否能找到可能发生过度释放的地方。
最后,尝试打开僵尸并查看是否可以重现崩溃。
答案 1 :(得分:-2)
如果你这样做会有帮助吗?
NSArray * allKeys = [NSArray arrayWithArray:[allItems allKeys]];