4

我目前正在处理的代码需要将 NSNumber 对象添加到数组中。所有值为 0-12 的 NSNumber 都可以正常添加,但 13 之后会导致 EXC_BAD_ACCESS。我打开了 NSZombieEnabled,现在正在获取*** -[CFNumber retain]: message sent to deallocated instance 0x3c78420.

这是调用堆栈:
#0 0x01eac3a7 in ___forwarding___
#1 0x01e886c2 in __forwarding_prep_0___
#2 0x01e3f988 in CFRetain
#3 0x01e4b586 in _CFArrayReplaceValues
#4 0x0002a2f9 in -[NSCFArray insertObject:atIndex:]
#5 0x0002a274 in -[NSCFArray addObject:]
#6 0x00010a3b in -[Faves addObject:] at Faves.m:24
#7 0x000062ff in -[ShowController processFave] at ShowController.m:458
#8 0x002af405 in -[UIApplication sendAction:to:from:forEvent:]
#9 0x00312b4e in -[UIControl sendAction:to:forEvent:]
#10 0x00314d6f in -[UIControl(Internal) _sendActionsForEvents:withEvent:]
#11 0x00313abb in -[UIControl touchesEnded:withEvent:]
#12 0x002c8ddf in -[UIWindow _sendTouchesForEvent:]
#13 0x002b27c8 in -[UIApplication sendEvent:]
#14 0x002b9061 in _UIApplicationHandleEvent
#15 0x02566d59 in PurpleEventCallback
#16 0x01e83b80 in CFRunLoopRunSpecific
#17 0x01e82c48 in CFRunLoopRunInMode
#18 0x02565615 in GSEventRunModal
#19 0x025656da in GSEventRun
#20 0x002b9faf in UIApplicationMain
#21 0x00002498 in main at main.m:14

如果它没有被隔离到某个范围的 NSNumbers,我会假设我的内存管理搞砸了,但我只是不知道。

有任何想法吗?

谢谢,
乔什

4

2 回答 2

11

正如我在这里回答另一个问题时发现的那样,数字 0 到 12 很特殊。请记住,这是一个实现细节,而不是语言规范。

基本上,最多(包括)12 的数字为您提供了对已经存在的 NSNumber 的引用,这是可能的,因为它们是不可变的。调查显示,13 或更大的数字给出了一个单独的实例。

所以你可能已经搞砸了你的内存管理:-) 只是小于 13 的数字可能是对已经存在的数字的引用,这在这些情况下可以节省你的培根。我建议您发布更多代码,以便我们可以追踪该特定问题。


根据您对此处另一个答案的评论:

我在代码中添加了一条保留行,现在一切正常。不知道为什么。我只是要顺其自然。谢谢!

我想您会发现,小于 13 的 NSNumber 在您获得自己的保留计数之前已经保留计数为 1(将计数增加到 2),这就是它们不会导致 EXC_BAD_ACCESS 的原因。显然,您的代码正在丢失您分配的所有数字,但系统并未释放 13 岁以下的数字,因为它们仍在使用中(保持 1 或更多的计数)。

于 2010-03-28T15:37:46.713 回答
2

显然 NSNumbers >12 将保留。我建议您编写一个非常小的程序来向自己证明这一点。然后获取该程序,使其成为一个函数,并在程序的早期调用它。慢慢地将函数移动到程序中的后面位置,直到出现错误。因此,您将找到真正的错误。

于 2010-03-28T15:13:44.017 回答