NSDictionary allKeys 崩溃 - 无法理解崩溃报告情况
Posted
技术标签:
【中文标题】NSDictionary allKeys 崩溃 - 无法理解崩溃报告情况【英文标题】:NSDictionary allKeys crashes - Cannot understand crash report circumstances 【发布时间】:2012-03-24 06:24:16 【问题描述】:我有以下代码:
- (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)
......
谢谢。
【问题讨论】:
您是否使用ARC?这似乎是与内存相关的错误。 等一下,您是否要向字典中添加原始整数?您正在尝试向内存 0x10 处的对象发送消息,这在您的应用程序中似乎是一个普通整数。 理查德,我们没有使用 ARC。 【参考方案1】: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() 处理,并且该结构恰好有一个指针作为第一个条目,这是结构的一种完全常见的模式。
修复?
首先,运行分析器并修复它抱怨的所有问题。
接下来,检查作为该字典键的对象的所有使用情况。看看你是否能找到可能发生过度释放的地方。
最后,尝试开启僵尸,看看能否重现崩溃。
【讨论】:
bbum 谢谢你这么详细的回复。我不知道所有这些低级信息,但您似乎确实知道。我们会仔细研究这个。再次感谢! 这个崩溃发生在我身上,因为我在与管理对象的线程不同的线程上调用了[myDict allKeys]
。正如这个答案所说,它是指向已释放对象的指针。以上是关于NSDictionary allKeys 崩溃 - 无法理解崩溃报告情况的主要内容,如果未能解决你的问题,请参考以下文章
为啥我得到“[__NSArrayI allKeys]:无法识别的选择器发送到实例”/为啥 NSDictionary 正在转换?
为啥我得到“[__NSArrayI allKeys]:无法识别的选择器发送到实例”/为啥 NSDictionary 正在转换?