我的核心数据实体在哪里?

Posted

技术标签:

【中文标题】我的核心数据实体在哪里?【英文标题】:Where are my core data entities? 【发布时间】:2011-10-30 07:09:25 【问题描述】:

我有一个预先存在的项目,我已向其中添加了 Core Data 模型。我添加了 Core Data 框架,添加了一个带有实体的数据模型,并将它与一些生成的 NSManagedObject 类一起包含在我的应用程序的目标中。它编译得很好,现在我想为我创建的实体添加一些测试。在these instructions 之后,我使用setUp 方法设置了一个逻辑测试基类,如下所示:

- (void)setUp 
    model = [NSManagedObjectModel mergedModelFromBundles:nil];
    NSLog(@"model: %@", model);
    coord = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:model];
    store = [coord addPersistentStoreWithType:NSInMemoryStoreType
                                configuration:nil
                                          URL:nil
                                      options:nil 
                                        error:NULL];
    ctx = [[NSManagedObjectContext alloc] init];
    [ctx setPersistentStoreCoordinator:coord];

这会编译并创建所有对象。但是,模型没有实体! NSLog() 输出如下所示:

2011-10-29 23:56:58.941 otest[42682:3b03] model: (<NSManagedObjectModel: 0x19c6780>) isEditable 1, entities 
, fetch request templates 

那么我的实体在哪里?我浏览了这个包,也没有.momd 文件。我是否错过了构建模型的关键步骤?

【问题讨论】:

您的意思是您已将实体添加到模型中,还是添加了实体的实际实例,其中包含数据? 核心数据中有很多延迟加载 - 文档说加载模型不一定会加载实体 - 如果您记录 [模型实体] 会发生什么? @jrturton:我已将实体添加到我的模型中。 [模型实体] 返回一个空数组。 【参考方案1】:

我做了一些额外的Duck Duck Going 并设法在this answer 中找到我需要的信息。结果是,因为测试目标不使用“主”包,所以我必须实例化测试包。所以代替这一行:

    model = [NSManagedObjectModel mergedModelFromBundles:nil];

我现在有这三行:

    NSBundle *bundle = [NSBundle bundleWithIdentifier:@"com.example.LogicTests"];
    NSURL *url = [bundle URLForResource:@"MyModels" withExtension:@"momd"];
    model = [[NSManagedObjectModel alloc] initWithContentsOfURL:url];

包标识符直接来自我的目标构建信息,而“MyModels”来自我的数据模型文件,该文件名为“MyModels.xcdatamodeld”并作为“MyModels.momd”包含在应用包中。当然,其中包含我的模型。

【讨论】:

太好了,这个答案对我有帮助,谢谢。但是我使用 Apple 的代码来处理 Core Data,所以我刚刚将 [NSBundle mainBundle]; 更改为 [NSBundle bundleWithIdentifier:@"com.example.someProject"];【参考方案2】:

看这里。我正在使用您使用 CoreData 创建项目时生成的代码。我希望这能帮助您解决问题:

pragma mark 核心数据栈

@property (nonatomic, retain, readonly) NSManagedObjectModel *managedObjectModel;
@property (nonatomic, retain, readonly) NSManagedObjectContext *managedObjectContext;
@property (nonatomic, retain, readonly) NSPersistentStoreCoordinator *persistentStoreCoordinator;


/**
 Returns the managed object context for the application.
 If the context doesn't already exist, it is created and bound to the persistent store coordinator for the application.
 */
- (NSManagedObjectContext *) managedObjectContext 

    if (managedObjectContext != nil) 
    
        return managedObjectContext;
    
    
    NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
    if (coordinator != nil) 
    
        managedObjectContext = [[NSManagedObjectContext alloc] init];
        [managedObjectContext setPersistentStoreCoordinator: coordinator];
    
    return managedObjectContext;



/**
 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;
    
    managedObjectModel = [[NSManagedObjectModel mergedModelFromBundles:nil] retain];    
    return managedObjectModel;



/**
 Returns the persistent store coordinator for the application.
 If the coordinator doesn't already exist, it is created and the application's store added to it.
 */
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
   
    if (persistentStoreCoordinator != nil) 
    
        return persistentStoreCoordinator;
    
    
    NSURL *storeUrl = [NSURL fileURLWithPath: [[self applicationDocumentsDirectory] stringByAppendingPathComponent: @"CoreDB.sqlite"]];
    
    NSError *error = nil;
    persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
    NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
                             [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption, 
                             [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];
    if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:options error:&error])
    
        /*
         Replace this implementation with code to handle the error appropriately.
         
         abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. If it is not possible to recover from the error, display an alert panel that instructs the user to quit the application by pressing the Home button.
         
         Typical reasons for an error here include:
         * The persistent store is not accessible
         * The schema for the persistent store is incompatible with current managed object model
         Check the error message to determine what the actual problem was.
         */
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();
    
    return persistentStoreCoordinator;

【讨论】:

我也试过了,但无法弄清楚可能缺少什么,但我会再倒一遍。【参考方案3】:

如果您的数据库在框架内/来自框架,则需要使用相应的 Bundle 加载它。

我在 Swift 中找到了MagicalRecord 的解决方案:

let frameworkBundle = Bundle(for: AClassFromTheFramework.self)
let managedObjectModel = NSManagedObjectModel.mergedModel(from: [frameworkBundle])
MagicalRecord.setShouldAutoCreateManagedObjectModel(false)
NSManagedObjectModel.mr_setDefaultManagedObjectModel(managedObjectModel)
MagicalRecord.setupCoreDataStack(withAutoMigratingSqliteStoreNamed: "db.sqlite")

从包中加载管理对象模型并将setShouldAutoCreateManagedObjectModel 设置为false 就成功了!

【讨论】:

以上是关于我的核心数据实体在哪里?的主要内容,如果未能解决你的问题,请参考以下文章

数据核心 NSException

在哪里为 Swift 中的核心数据实现 NSValueTransformer

以编程方式设置核心数据 - NSManagedObjectContext 来自哪里?

我的核心数据数据模型中的一个实体没有被删除

如何为我的核心数据实体建模?

向核心数据实体添加属性