Core Data迁移后的NSRangeException [英] NSRangeException following Core Data migration

查看:217
本文介绍了Core Data迁移后的NSRangeException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

将新的Core Data模型版本添加到我的应用程序后,我执行了轻量级迁移,显然已成功。已迁移的文件已正常加载,但是在首次尝试通过特定关系访问属性时,应用程序会使用 NSRangeException:'*** - [__ NSArrayM objectAtIndex:]:崩溃:index 4294967295超出bounds [0 .. 35]'。这种关系在迁移之前运行良好。我从其他帖子知道4294967295是真的 -1 ,但我唯一可以识别36项目在我的应用程序/数据中是有36个实体在数据模型(供参考,正在获取的关系在其表中有58个项目)。



我的问题是:根据错误我'获取和我在下面做的故障排除是否有一种类型的模式更改可以通过轻量级迁移,但损坏的数据的方式,导致注意的异常?我将尝试将迁移分解成多个版本的更小的块,以隔离或避免该问题,但是能够专注于可能有故障的特定架构更改将是很好的。



失败:



myobject中的以下代码失败:

  [[self object2] text]; 

object2关系是一个,非可选的两种方式,在数据模型之间更改。 text 属性可能不相关,因为当错误发生时,object2中未达到 awakeFromFetch 。如果在上述语句之前将 [self object2] 分配给一个变量,则赋值成功并报告 data:< fault>



数据库



sqlite3,我注意到以下:


  1. 正向和反向关系的索引值在每个表中都是正确的。

  2. object2表具有两个反向关系列,而不是迁移前的 ZMYOBJECT 和附加的 Z2_MYOBJECT ,对于所有行为空)。

  3. Z_PRIMARYKEY 表中,迁移后的所有条目都显示 -1 为 Z_MAX ,而在迁移之前,它们对于空表和对于填充表的最大行数显示为零。手动将 Z_MAX 更新为正确的值对此异常没有帮助。 Z_SUPER 的值是正确的。

我设置了一个映射模型



整体模式变更



在数据模型的源版本中,有十四个实体,其中只有四个实体已填充数据(应用程序仍在开发中)。七个是顶级实体,七个是三个顶级实体的子实体。



在数据模型的目标版本中,有二十二个实体添加,一些顶级和一些子实体,具有几十个关系,包括添加到现有实体的一些关系。



一些属性和关系从现有实体和其他。



更新(2/25/12):当我开始使用的时候,没有改变数据类型或关系设置,没有重命名属性或关系,工作在一个新的中间模型,我记得我已经改变了一些实体从NSManagedObject到NSManagedObject子类的类(resentClassName),但没有生成类文件。我没有怀疑会导致一个问题,确实,创建所有的类文件没有帮助的异常。



>这是一个疯狂的猜测,但如果36个实体计数不是巧合,似乎当myobject尝试在对象2中的故障它没有有效的表的引用,并尝试加载表号 - 1,引起异常。然而, [self object2] 的简单赋值成功的事实不会得出结论。



任何想法?

解决方案

通过几个增量迁移,我能够确定导致问题的原因,



有数据的现有实体之一没有子实体。如果我创建一个新模型,只添加一个子实体,不包含任何属性或关系,并且不做任何其他更改,NSRangeException,Z_MAX观察,以及我的问题中指出的反比关系的加倍。



解决方案:



观察上述情况下成功我创建了一个映射模型。因为唯一的变化是一个额外的实体,除了一个实体映射之外,所有实体映射都是直接的。



默认情况下,没有属性或关系的添加实体显示所有的属性和关系映射父级的属性。默认情况下,所有映射都具有空值表达式,我假设这意味着它只是在迁移过程中跳过它们。不是真的,显然。通过删除实体映射中的所有属性和关系映射,然后关闭推断映射,迁移将成功进行。



我仍然必须处理所有剩余的实体并将尝试这种方法来批量处理其余所有计划的属性和关系。


After adding a new Core Data model version to my app, I performed a lightweight migration, apparently successfully. The migrated file loaded fine, but upon the first attempt to access an attribute via a particular relationship, the app crashes with an NSRangeException: '*** -[__NSArrayM objectAtIndex:]: index 4294967295 beyond bounds [0 .. 35]'. This relationship worked fine prior to the migration. I know from other posts here that 4294967295 is really -1, but the only thing I can identify with 36 items in my app/data is that there are 36 total entities in the data model (for reference, the relationship that's being fetched has 58 items in its table).

The question:

My question is: based on the error I'm getting and the troubleshooting I've done below, is there a type of schema change that could pass the lightweight migration, but corrupt the data along the way, leading to the noted exception? I'm going to try breaking down the migration into smaller chunks over several versions to either isolate or avoid the issue, but it would be nice to be able to focus on specific schema changes that might be at fault.

The failure:

The failure occurs with the following code in "myobject":

[[self object2] text];

The object2 relationship is to-one, non-optional both ways and neither the forward nor inverse relationship was changed between data models. The text attribute is likely not relevant because when the error occurs, awakeFromFetch is not reached in object2. If I assign [self object2] to a variable prior to the above statement, the assignment is successful and reports data: <fault>.

The database:

Looking at the database in sqlite3, I notice the following:

  1. The index values for the forward and inverse relationships appear to be correct in each table.
  2. The object2 table has two columns for the inverse relationship instead of the one prior to migration (ZMYOBJECT as before and the additional Z2_MYOBJECT, which is empty for all rows). No other relationship were added to explain this column.
  3. In the Z_PRIMARYKEY table, all entries post-migration show -1 for Z_MAX, whereas prior to migration they showed zero for empty tables and the maximum row number for populated tables. Manually updating Z_MAX to the proper values did not help with the exception. All Z_SUPER values were correct.

I set up a mapping model to see if anything looked awry with the automatic mappings, but everything looked fine.

Overall schema changes:

In the source version of the data model, there were fourteen entities, of which only four had been populated with data (the app is still in development). Seven were top-level entities and seven were sub-entities of three of the top-level entities.

In the target version of the data model, twenty-two entities were added, some top-level and some sub-entities, with dozens of relationships, including some added to existing entities.

Some attributes and relationships were removed from existing entities and others were added. No data types or relationship settings were changed, no attributes or relationships were renamed, and no special mappings were required.

Update (2/25/12): As I started working on a new intermediate model, I remembered that I had changed the class (representedClassName) for a number of entities from NSManagedObject to an NSManagedObject subclass, but hadn't generated the class files. I didn't suspect that would cause an issue and, indeed, creating all of the class files did not help with the exception. I just wanted to note that as another change between models.

Conclusions:

This is a wild guess, but if the 36 entity count is not a coincidence, it seems that when "myobject" attempts to fault in "object2" it does not have a valid reference for the table and is attempting to load table number -1, causing the exception. The fact that a simple assignment of [self object2] is successful, however, doesn't jibe with that conclusion.

Any ideas?

解决方案

By working through several incremental migrations I was able to determine what is causing the issue, and a solution.

The problem:

One of the existing entities with data has no child entities in the current model. If I create a new model that simply adds a child entity, containing no attributes or relationships, and makes no other changes, the NSRangeException, Z_MAX observation, and doubling of the inverse relationship noted in my question all occur.

The solution:

After observing the failures following a "successful" lightweight migration for the case above, I created a mapping model. Since the only change was one additional entity, all but one of the entity mappings were straightforward. The question was what to do with the single added entity.

By default, the added entity with no attributes or relationships of its own was showing attribute and relationship mappings for all of the parent's properties. All of the mappings had empty value expressions by default, which I assumed meant that it would just skip them during the migration. Not true, apparently. By deleting all of the attribute and relationship mappings within the entity mapping and then turning off inferred mapping, the migration proceeded successfully.

I still have to tackle all of the remaining entities and will be trying this approach to do the rest in bulk, with all planned attributes and relationships intact.

这篇关于Core Data迁移后的NSRangeException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆