Objective c NSNumber>;=13韩元';我不能保留。其他一切都会

Objective c NSNumber>;=13韩元';我不能保留。其他一切都会,objective-c,iphone,debugging,nsnumber,Objective C,Iphone,Debugging,Nsnumber,我目前正在处理的代码需要向数组中添加NSNumber对象。所有值为0-12的NSNumbers都可以添加,但13以后的NSNumbers将导致EXC_BAD_访问。我启用了NSZombieEnabled,现在收到了发送到解除分配实例0x3c78420的消息 这是调用堆栈: #0 0x01eac3a7 in uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu #1 0x01e886c2在uuu转发u准备uu

我目前正在处理的代码需要向数组中添加NSNumber对象。所有值为0-12的NSNumbers都可以添加,但13以后的NSNumbers将导致EXC_BAD_访问。我启用了NSZombieEnabled,现在收到了发送到解除分配实例0x3c78420的消息

这是调用堆栈:
#0 0x01eac3a7 in uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
#1 0x01e886c2在uuu转发u准备uu 0 uuuu

CFRetain中的2 0x01e3f988
#3 0x01e4b586 in\u CFArrayReplaceValues

#4 0x0002a2f9英寸-[NSFarray插入对象:atIndex:][/code>
#5 0x0002a274英寸-[NSCFArray addObject:][/code>
#6 0x00010a3b in-[Faves addObject:]位于Faves.m:24

#7 0x000062ff在ShowController.m:458处的[ShowController processFave]中
#8 0x002af405 in-[UIApplication sendAction:to:from:forEvent:][/code>
#9 0x00312b4e in-[UIControl发送操作:发送到:forEvent:][/code>
#10 0x00314d6f in-[UIControl(内部)\u发送操作预防:with event:://代码>
#11 0x00313abb in-[UIControl触摸预定:withEvent:]

#12 0x002c8ddf in-[UIWindow\u sendTouchesForEvent:][/code>
#13 0x002b27c8 in-[UIApplication sendEvent::][/code>
应用程序HandleEvent中的14 0x002b9061
#15 0x02566d59紫色回拨

CFRunLoopRunSpecific中的16 0x01e83b80 cfrunloop运行模式下的17 0x01e82c48 GSEventRunModal中的18 0x02565615 GSEventRun中的19 0x025656da UIApplicationMain中的20 0x002b9faf
#21 0x00002498在main的main中。m:14

如果它不是孤立于特定范围的NSN数字,我会认为我的内存管理出了问题,但我只是不知道

有什么想法吗

谢谢,

Josh

显然NSNumbers>12将保留。我建议你写一个非常小的程序来证明这一点。然后把这个程序变成一个函数,在程序的早期调用它。缓慢地将函数移动到程序中的稍后点,直到出现错误。因此,您将找到真正的bug。

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

基本上,12之前(包括12)的数字会给你一个已经存在的NSNumber的引用,这是可能的,因为它们是不可变的。调查显示,数字13或更高给出了一个单独的例子

所以你可能已经把你的内存管理搞砸了:-)只是事实上,小于13的数字很可能是对已经存在的数字的引用,在这些情况下,这节省了你的时间。我建议你发布更多的代码,这样我们就可以追踪那个特定的问题


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


我在代码中添加了一行retain,现在一切都很好。不知道为什么。我只是想顺其自然。谢谢


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

我在代码中添加了保留行,现在一切正常。不知道为什么。我只是想顺其自然。谢谢@jkap我可以建议您花点时间研究一下内存管理规则,并找出它为什么现在可以工作吗?如果您了解如何解决此问题,将来出现类似问题的可能性就会降低。@jkap:在代码中添加随机保留将导致最终出现大量内存泄漏的不可释放程序。一旦你摸索过,保留/释放规则实际上是非常清楚的,所以花点时间去了解到底发生了什么。这是因为ObjC有triskaidekaphobia:p.迷人!像“数字0到12是特殊的”这样的陈述不能不经过测试,瞧,你绝对正确哇!这是非常错误的。这是我最讨厌Objective-C的地方之一。所有数字都应该是不变的。所有字符串都应该是不可变的。Python做对了。有那么一秒钟,@vy32,我还以为你在尝试我的答案是“错得太多”,而不是ObjC行为。:-)但我不确定我是否理解你。NSNumber确实是不可变的,这就是使这种优化成为可能的原因(例如,你不能改变NSNumber(15)后面的数字来搞乱其他使用它的人)。不,“如此错误”适用于苹果,而不是你。如果数字是不可变的,那么为什么要使它们特别呢?或者为什么要在12米处划出截止线,而不是在1米处?这太武断了……嗯,这只是一种优化。他们似乎已经决定使用最多12个数字,因此值得提前设置它们,或者可能他们有一个运行缓慢的演示时钟应用程序,他们想让它看起来更好:-)我可能会停止预分配-1、0和1,因为它们是最常见的。但有一个权衡。你可以分配多达一百万的内存,但这会占用相当大的内存来存储很多没人会用到的数字。想想你在应用程序中需要174563这个数字的次数。