Iphone 如何查找:-[CFArray\u cfTypeID]:发送到解除分配实例的消息的匹配对象

Iphone 如何查找:-[CFArray\u cfTypeID]:发送到解除分配实例的消息的匹配对象,iphone,memory-management,Iphone,Memory Management,我被这条错误消息困住了,因为有三天我没有找到对象\u cfTypeID,也没有在那条消息后记录对象的地址。我知道我必须访问一个数组,但它已被销毁 我的iPhone应用程序基于一个选项卡栏控制器,通过一个选项卡,我切换到一个新的视图控制器,该控制器创建一个导航视图控制器,并隐藏整个选项卡栏控制器,使其不被访问。我选择这种方式是因为整个选项卡栏视图逻辑以纵向方向运行,而导航视图控制器以横向方向运行 当第一次运行通过选项卡栏从任何纵向视图开始,并更改为导航视图控制器的横向视图时,它总是可以运行的。我在

我被这条错误消息困住了,因为有三天我没有找到对象\u cfTypeID,也没有在那条消息后记录对象的地址。我知道我必须访问一个数组,但它已被销毁

我的iPhone应用程序基于一个选项卡栏控制器,通过一个选项卡,我切换到一个新的视图控制器,该控制器创建一个导航视图控制器,并隐藏整个选项卡栏控制器,使其不被访问。我选择这种方式是因为整个选项卡栏视图逻辑以纵向方向运行,而导航视图控制器以横向方向运行

当第一次运行通过选项卡栏从任何纵向视图开始,并更改为导航视图控制器的横向视图时,它总是可以运行的。我在导航堆栈上推送了三个视图。在第一次运行时,当我导航回根控制器时,也没有崩溃,保持此状态并返回到选项卡栏控制器的最后一个可见视图。此时,导航视图控制器将被解除分配

崩溃发生在第二次运行时,再次从选项卡栏控制器导航到导航视图控制器,再导航到第三次按下的视图控制器。此时将重新创建导航视图控制器及其堆栈上的三个视图控制器。当我通过按backBarButton或rightBarButton(我已创建为“完成”按钮)离开堆栈上最底部的视图时,会发生崩溃

我还没有找到内存管理不好的地方,因为我自己没有一个名为_cfTypeID的数组,也没有直接访问这个数组。GDB在调用同步NSUserDefaults的过程中崩溃,我在ViewWill中使用的NSUserDefaults将从刚刚离开屏幕的视图中消失。带有泄漏工具的仪器在崩溃后终止进程,其消息对我没有帮助

…在模拟器中运行与在设备(即iPhone 4)上运行之间存在行为差异:在设备上,我可以从导航视图控制器中弹出多个视图控制器,并在通过backBarButton离开视图时发生崩溃

我决定不发布任何代码行,因为代码行太多了,放在这里可能没有意义。但如果需要,我可以提供部分。我会很高兴能找到一些工具,我可以用它来识别坏的数组或其他任何东西来修改我的内存管理(这当然不是完美的,因为我对C++和PHP的Objc非常新。) 干杯,
Konran

\u cfTypeId
不是数组的名称,而是发送到
CFArray
实例的消息的名称。具体的错误来自框架代码内部的某个地方,这就是为什么您无法识别它的任何内容,但原因是代码中的某些内容要么没有保留它应该保留的内容,要么发布了它不应该发布的内容,要么过早地发布了它仍然希望使用的内容


顺便说一句,不要使用
retainCount
,它不会像你想象的那样工作,通常是无用的。

好的,非常奇怪-但它是:

- (void)loadPrefs
{
NSUserDefaults* prefs  = [NSUserDefaults standardUserDefaults];
NSMutableArray* tmpArr = nil;

// initialize currency name color array
if ((tmpArr = (NSMutableArray*)[diagView loadPrefsColorArray:@"diagCellColors"]) != nil)
    self.cellColors = [NSMutableArray arrayWithArray:tmpArr];
else
    self.cellColors = [diagView defaultCellColors];

tmpArr = nil;   //+++ added this to release tmpArr

// initialize currency arrays
if ((tmpArr = [prefs objectForKey:@"diagUsedCurrencies"]) != nil)
    self.arrCurrencies = [NSMutableArray arrayWithArray:tmpArr];
else
    self.arrCurrencies = [NSMutableArray arrayWithCapacity:1];

tmpArr = nil;   //+++ added this to release tmpArr
...

在我的原始代码中,我仅在从该方法返回之前将tmpArr设置为nil。事实上,我不明白为什么需要重置tmpArr,因为我保留了自己的引用(如self.cellColors中的保留属性)。我几乎所有的视图控制器都有类似的构造,只有在一个例子中出现了未定义的崩溃。

错误肯定与您实现的阵列有关,并且没有足够的内存。如果您实现了一个自动释放数组,但忘记了以后需要它,那么这种情况尤其常见。请尝试使用调试器/工具查找问题。谢谢,但问题是我拥有的所有数组都没有名称\u cfTypeID。。。我简直找不到那个名字的任何参考资料。因此,到目前为止,所有调试器/工具活动都失败了。在创建之后和销毁导航视图控制器之前,我用address和retain count记录了所有视图控制器实例、数组和字典。除了使用[self.thecctrl pushViewController:viewControl animated:NO]在堆栈上推送的第一个视图控制器外,它看起来都很好(保留计数2,导航视图控制器3);在我销毁它之前,它的保留计数是27和2。好的,这会给它注入一些光。。。即使我还没找到。它似乎真的在单视图控制器中,当我按下任何导航栏按钮时,崩溃被初始化。我在堆栈上移动了一些视图控制器,并插入/附加了一个虚拟对象,它总是在同一个地方消亡。我会继续研究…谢谢,找到了。请参阅下面的代码,因为这里没有合适的格式。在那里指定nil实际上不会释放任何内容。我猜在某个时刻,tmpArr将保留其旧值,而不是被分配到您认为应该是的值。他们会让你释放它,不小心释放了旧的值(可能是已经自动释放的值)。谢谢Anomie。无论如何,我觉得奇怪的是,它碰巧意外地释放了旧值。。。self.cellColors由setter方法调用,因此由其属性保留一次。我不明白为什么对tmpArr的第二次赋值(w/out将其值重置为nil)会释放旧值。嗯。无论如何,我会继续像以前一样解决它。代码中没有意外。。。更可能的情况是,您刚刚移动了问题,它将在未来神秘地崩溃,只是需要处理更多的代码和更复杂的问题。你有没有尝试使用NSZombies或其他工具来追踪这类问题?嗯,听起来比预期的更糟。我已经在我的项目中启用了NSZombie,只要它还没有完成。由于静态分析器的错误,我已经清理了代码