viewWillAppear vs viewDidAppear内存错误

时间:2014-07-04 18:18:37

标签: ios memory-management ios7 uiviewcontroller xcode5

在我的游戏中,我有一个功能,可以构建世界地图并配置相关的数据结构。我一直在从相关的View Controllers'中调用它。 viewWillAppear函数持续数月,一切都按预期工作。

今天,我明智地将世界设置调用移动到viewDidAppear,然后显示进度指示器。此时,设置功能开始在98.5%的时间内抛出异常。它实际工作的几次,我收到了内存警告。将回调移回viewWillAppear完全解决了问题(和警告)。但是,我无法轻易放弃并继续调试。

我有这个部分决定在哪里建造河流。在该段中,检查相邻单元的高度以确保河流始终向下流动。在那个部分中,我简单地使用了四个(非角落)邻居的冒泡排序,在评估可能的河流位置时调用它们:

        for (int i=0; i<4; i++)
        {
            for (int j=0; j<4-i; j++)
            {
                if (candidates[j].tileType > candidates[j+1].tileType)
                {
                    struct riverCandidate temp = candidates[j+1];
                    candidates[j+1] = candidates[j];
                    candidates[j] = temp;
                }

            }

        }

最终,我在排序之前和之后得到了足够多的NSLog候选人[]的价值。我发现,当从viewWillAppear调用整个事件时,它在100%的时间内完美无瑕地工作。但是,当从viewDidAppear调用时,偶尔会有一个候选[]元素被随机破坏(当我随后尝试访问它时会导致上述异常)。我不能说我发现了任何明显的腐败模式,除了a)4个中只有一个元素一次被破坏而b)我只看到第一个[0]和最后[3]个元素被破坏了。在世界设置过程中,这段代码可能被称为几十次,并且大多数传递都是成功的......但是只需要其中一个传递就不能搞砸下游的工作。

为了解决这个问题,我所做的就是将temp的定义移到循环之外,如下所示:

        struct riverCandidate temp;
        for (int i=0; i<4; i++)
        {
            for (int j=0; j<4-i; j++)
            {
                if (candidates[j].tileType > candidates[j+1].tileType)
                {
                    temp = candidates[j+1];
                    candidates[j+1] = candidates[j];
                    candidates[j] = temp;
                }

            }

        }

现在,当从viewDidAppear调用时,它有100%的时间工作,没有男人警告。

所以这是我的问题:为什么在viewWillAppear和viewDidAppear之间行为会发生变化?如果有一个具有malloc的临时结构的潜在竞争条件,为什么它永远不会发生viewWillAppear并且几乎总是发生在viewDidAppear中?

我希望更好地理解这种行为,以免我再次陷入其中。

更新:所以移动temp的定义实际上并没有帮助。猜猜我很幸运,有一系列成功的运行让它看起来很有效。经过更多调试后,我终于注意到上面的j循环有一个拼写错误,让它写入数组的末尾,并更正了。

但是这仍然让我感到困惑:当我从viewWillAppear调用时,我怎么也从来没有打过它,但是当我将函数调用移到viewDidAppear时总是点击它?我一定错过了一些明显的东西。

由于

0 个答案:

没有答案