6

我遇到了一些我遇到问题的 beta 测试人员的奇怪崩溃。符号化的崩溃报告表明崩溃发生在作为单例的控制器的简单分配中,在 init 调用中,但根据堆栈跟踪,看来我所拥有的代码init实际上并不是崩溃所在的位置。以下是相关代码:

1534| + (UA[REDACTED]PlayerController*)sharedInstance
1535| {
1536|     @synchronized(self)
1537|     {
1538|         if (sharedInstance == nil)
1539|     sharedInstance = [[UA[REDACTED]PlayerController alloc] init];
1540|     }
1541|     return sharedInstance;
1542| }

这以前从未崩溃过,而且代码最近也没有任何变化。这是引发的堆栈跟踪:

Thread 5:
0   libSystem.B.dylib              0x33bd52d4 __kill + 8
1   libSystem.B.dylib              0x33bd52c4 kill + 4
2   libSystem.B.dylib              0x33bd52b6 raise + 10
3   libSystem.B.dylib              0x33be9d26 __abort + 62
4   libSystem.B.dylib              0x33be9d7e abort + 62
5   libSystem.B.dylib              0x33bd7980 __assert_rtn + 152
6   libgcc_s.1.dylib               0x32acab4e _Unwind_SjLj_Resume + 26
7   [REDACTED]                     0x00060b64 +[UA[REDACTED]PlayerController sharedInstance] (UA[REDACTED]PlayerController.m:1540)
8   [REDACTED]                     0x00063e6c -[UA[REDACTED]PlayerViewController setupControlViews] (UA[REDACTED]PlayerViewController.m:224)
9   [REDACTED]                     0x00062ce0 -[UA[REDACTED]PlayerViewController viewDidLoad] (UA[REDACTED]PlayerViewController.m:268)
10  UIKit                          0x320a0270 -[UIViewController view] + 104
…

关于这个神秘的崩溃是什么以及它可能来自哪里的任何想法?





更新 1
它似乎与核心数据和迁移有关。我能够复制它,但根本原因仍然未知。我在这个版本中有一些自动迁移,看起来虽然可以读取一些 NSManagedObjects,但其他人正在抛出这个异常,特别是在 NSManagedObjects 关系上。可能根本就没有关系PlayerController。任何核心数据专家都有一些见解?




更新 2
这是我找到重现它的方法替代文字
和相关代码后崩溃的调用堆栈:

if (resultArray && [resultArray count]) {
    for (MixAudio *ma in resultArray) {
        Audio *audio = [ma valueForKey:LOCAL_MIX_AUDIO_AUDIO_KEY];
        if (audio) {
            [returnArray addObject:audio];
    }
}

为了帮助解释我做了什么来重现它,我必须稍微解释一下数据结构。我有MixAudio项目。混音有很多音频,音频属于很多混音。这是对 MixAudio 对象的简单关系调用以获取音频。现在,这只是在我将数据库还原到新版本后才崩溃。

我的设置中的数据库备份意味着压缩数据库以保存数据,然后在还原时解压缩。此崩溃仅在还原过程之后发生。更复杂的是,有 3 个带有映射模型的数据库版本。因为这个过程在版本控制之前对我有用,所以我觉得我的版本中的某些东西导致了这个崩溃。

所有其他数据都很好,可以访问,甚至保存。不知何故,这个单一的提取导致了问题。设置持久存储或托管对象模型时没有错误或警告。此外,可以很好地创建和访问新的 Mix 对象,只有较旧的提取(在还原之前位于数据库中)失败。

如果我没有发现错误,控制台会打印:

Assertion failed: (_Unwind_SjLj_Resume() can't return), function _Unwind_SjLj_Resume, file /SourceCache/libunwind/libunwind-24.1/src/Unwind-sjlj.c, line 326.

在崩溃线周围放置 atry/catch可以让我检查根本崩溃原因:

Error: NSRangeException: *** -[NSMutableArray objectAtIndex:]: index 4294967295 beyond bounds [0 .. 16]

valueForKey但这对于一个简单的电话来说毫无意义(至少对我来说) 。4294967295 = 2^32-1 这意味着如果有帮助,索引 var 可能设置为 -1。我在这里迷路了。





[已解决] 更新 3
我在版本控制中是对的 :) 我重新阅读了Zarra 书中关于版本控制的部分,并且有一个重要的DOH时刻。这是我第一次拥有具有 3 个数据库版本的应用程序。我在我的应用程序中使用映射模型,我天真地假设核心数据能够使用一个模型从 1-2 映射,然后使用下一个模型映射 2-3。当我意识到我没有 1-3 映射模型时,我真的撞到了头。为了测试它,我快速添加了一个,一切都像黄油一样光滑。现在我只需要回去使用他的Progressive Data Migration样本来让我的生活更轻松,因为我继续使用更多版本的数据库。

我希望 Zarra 开车经过这里并回答一些事情……任何事情……这样我就可以给他分数了 :)

4

1 回答 1

2

虽然 OP 能够解决他自己的问题,但对迁移有一个清晰的了解是有帮助的。

当您创建数据模型的第二个版本时,您需要一个从版本一到版本二的映射模型。

当您创建第三个模型时,您需要一个从一到二的映射模型一个从一到三的映射。

添加第四个模型时,您需要以下模型:

  • 1-2
  • 1-3
  • 1-4
  • 2-3
  • 2-4

它从那里得到更多的进步。

于 2011-01-10T05:57:33.023 回答