2010-02-17 90 views
11

我试图在CoreData中使用迁移功能。我遵循Apple文档。我在下面的方法存在问题:使用mergedModelFromBundles:和版本控制(CoreData)

/** 
Returns the managed object model for the application. 
If the model doesn't already exist, it is created by merging all of the models found in the application bundle. 
*/ 
- (NSManagedObjectModel *)managedObjectModel { 

    if (managedObjectModel != nil) { 
     return managedObjectModel; 
    } 
    /* 
    * NSInvalidArgumentException', reason: '*** -[NSCFArray insertObject:atIndex:]: attempt to insert nil' 
    * 2010-02-17 16:27:15.338 Patrimoine[3037:207] 
    */ 
    managedObjectModel = [[NSManagedObjectModel mergedModelFromBundles:nil] retain];  
    return managedObjectModel; 
} 

看来,有上http://iphonedevelopment.blogspot.com/2009/09/core-data-migration-problems.html

但我选择了苹果的建议,通过使用菜单选项的方法相同的问题“添加模型版本”。

你有什么想法吗?

回答

27

你需要清理你的项目。只要你的“版本”你的模型Xcode将其移动到一个包(文件夹),但它不会删除旧的。接下来发生的事情是,当你下次运行你的应用程序时,你的模型有两个副本;旧的和在妈妈包里面的新的。

做一个项目 - >清洁所有将解决这个问题。

+0

这很完美!谢谢! – charlax 2010-02-18 18:13:49

+0

清洗不一定能解决问题。 Xcode不会从已安装的应用程序中删除旧的资源文件,即使在完整的构建之后。使用initWithContentsOfURL而不是mergedModelFromBundles至少可以将问题简化为只有一个文件夹中的旧.mom文件。 (我只是为这个问题奋斗了几天:http://stackoverflow.com/a/13146888/1017650) – Symmetric 2012-11-03 01:46:13

4

我发现使用mergedModelFromBundel:方法似乎不适用于迁移;我切换到-initWithContentsOfURL :,它工作正常。请注意,您必须使用指向“.momd”文件的URL来初始化它。

+0

我得到终止应用程序,由于未捕获的异常'NSInvalidArgumentException',原因:'无法创建NIL模型的NSPersistentStoreCoordinator'(文件的URL是正确的)。 这个错误发生在: 'persistentStoreCoordinator = [[NSPersistentStoreCoordinator页头​​] initWithManagedObjectModel:自managedObjectModel];' – charlax 2010-02-17 16:09:25

+0

有没有必要* *切换到initWithContentsOfURL :.根据Marcus的回答,问题在于您的构建产品仍包含旧模型。如果你只是做一个清洁,它会被修复。使用initWithContentsOfURL:因为你现在没有选择旧的模型。 – mmalc 2010-02-20 19:02:51

+0

实际上,由于Xcode不会删除旧的资源文件,因此有必要(请参阅我对@Marcus答案的评论)。 – Symmetric 2012-11-03 01:48:46

0

感谢大家!

这些都工作,但只有在我使用清洁构建选项后。

更多信息请参阅本其他堆栈溢出话题: Using mergedModelFromBundles: and versioning (CoreData)

iPhone的核心数据引用有一个相当不错的写了这一点。文档的正式流程是“轻量级自动迁移”。

再次感谢, --Batgar

9

另外,如果你在任何时候重命名你的模型,可以肯定,并再次切换到旧的然后回到新的模式重复“设置当前模型”的步骤。我的构建设置不会自动重置,并将“当前模型名称”设置为不存在的模型,导致完全相同的问题。

您可以始终在导入的.momd目录内的构建产品资源文件夹中,在名为versioninfo.plist的文件中验证此设置是否正确 - 当前模型的设置必须与您的模型的实际名称匹配。

+0

欢呼声对我来说很完美 – Abolfoooud 2011-10-07 16:34:59

+0

即使经过6年的付费iOS开发,我也不知道这个xcode的bug。仍然存在于Xcode 6.感谢堆! – Tim 2015-01-14 07:37:02

2

如果您在任何时候更改了您的数据模型,请务必在模拟器中重置内容和设置,否则将出现错误,即用于制作商店的模型版本与所用模型不一致访问它。

0

起初,没有提到的方法为我工作。 我正在使用XCode 4. 执行Clean,Clean Build Folder,找到.app文件以检查除了正确的文件(包含旧版本和新版本)之外,没有其他.xcdatamodel文件。 尝试使用initWithContentsOfURL :. 已验证当前版本对应于正确的版本,并在模拟器上进行了重置内容和设置。 然后编辑VersionInfo.plist并发现NSManagedObjectModel_CurrentVersionName值对应于一个不存在的版本名称!

因此,重新设置某个现有模型的当前版本名称(然后您会看到绿色复选标记正在改变),重建并运行。

仅供参考!

0

不幸的是,这不是清洁或版本问题。我有一个有点复杂的项目,有几层嵌套的Xcode项目。为了处理每个项目在不同SVN仓库中的问题,我设置了与我在Xcode“首选项 - >位置”中设置的特定源代码树相关的项目路径。例如,我设置了FACEBOOK_IOS_SDK_SRC来指向“〜/ Documents/{my_crazy_folder_structure}/facebook-ios-sdk/src”。这样,每当我的同事签出我的项目时,Facebook SDK的位置就与他们设置的任何路径有关,并且它们的机器不必与我的机器完全相同。我知道有更好的方法来处理这个问题,但它现在正在工作。

无论如何 - 我的问题出现了,因为在某些时候,我的* .xcdatamodel文件位置为“相对于{source_tree_path}”,它发现该文件很好,甚至将其编译为* .mom文件,但我在最初的问题中列出了这个疯狂的错误。我将我的位置更改为“相对于组”,并开始工作。我还没有找到确切的原因,但它浪费了一天调查的更好的一部分。希望这会在未来帮助别人。

0

我也开始碰到[[NSManagedObjectModel mergedModelFromBundles:nil]以及没有错误信息(典型的核心数据)。我最终意识到我已经用不同的模型命名了两个具有相同名称的实体,从而解决了这个问题。这就是为什么它为我崩溃。更改名称可以防止它崩溃。