在启动时未调用managedObjectContext

时间:2014-09-06 18:59:11

标签: ios core-data icloud nsmanagedobjectcontext

我正在将现有的Core Data应用程序修改为iCloud。我的问题是,当我在appDelegate中检测到初始应用程序启动后尝试加载种子数据时,我的第一个[NSEntityDescription insertNewObjectForEntityForName: inManagedObjectContext:]语句抛出错误“'NSInvalidArgumentException',原因:'+ entityForName:XXX nil不是合法的NSManagedObjectContext参数搜索实体名称'XXX''“我确定我传递的inManagedObjectContext参数是正确的,但果然,它在调试器中是零。

我的部分麻烦在于我不明白应用程序调用样板核心数据-managedObjectContext,-managedObjectModel和-persistentStoreCoordinators方法的原因。应用程序似乎总是调用方法并在需要时自动实例化这些对象。

核心数据堆栈基本上是核心数据应用程序模板的标准内容,iCloud选项添加到persistentStoreCoordinator,以及用于迁移现有数据的分支。这是代码;试图将其限制为基本要素:

@synthesize managedObjectContext = _managedObjectContext;
@synthesize managedObjectModel = _managedObjectModel;
@synthesize persistentStoreCoordinator = _persistentStoreCoordinator;

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // Notification registrations
    [self register_iCloudNotifications];

    // Data from defaults
    BOOL _firstLocalLaunch = ...
    BOOL _update = 
    BOOL _iCLoudDataSeeded = ...

    // FIRST APP LAUNCH LOCALLY; FIRST iCLOUD LAUNCH ANYWHERE
    // This is the code that's calling initializeSeedData and getting the error
    if (_firstLocalLaunch && !_iCloudDataSeeded) {
        [self initializeSeedData];
        ... update defaults

    } else if {
    ... code for update launch and normal launch

    // Safety check for seed data in persistent store; if none, initialize.
    NSFetchRequest *modelFetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *modelEntity = [NSEntityDescription entityForName:@"entity" inManagedObjectContext:self.managedObjectContext];
    [modelFetchRequest setEntity:modelEntity];
    NSArray *fetchResults = [_managedObjectContext executeFetchRequest:modelFetchRequest error:nil];
    if (!fetchResults.count) {
        NSLog(@"Safety catch: seed data missing");
        [self initializeSeedData];
    }

    return YES;
}

- (void)initializeSeedData
{
    SWSEntity *entity1 = [NSEntityDescription insertNewObjectForEntityForName:@"Entity" inManagedObjectContext:_managedObjectContext]; // THIS IS WHATS THROWING THE ERROR
    entity.name = @"First seed data item";
    [_managedObjectContext save:nil];
}

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

- (NSManagedObjectModel *)managedObjectModel
{
    if (_managedObjectModel != nil) {
        return _managedObjectModel;
    }
    NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"model" withExtension:@"momd"];
    _managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
    return _managedObjectModel;
}

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
    if (_persistentStoreCoordinator != nil) {
        NSLog(@"exists; returning");
        return _persistentStoreCoordinator;
    }

    _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];

    // NO UPDATE FROM PREVIOUS
    if (!_update) {
        NSLog(@"Persistent store: adding");
        [self add_iCloudPersistentStore];

    // UPDATE FROM PREVIOUS VERSION
    } else {
        NSLog(@"Persistent store: migrating");
        ...code for migrating existing store to iCloud; not called with this issue
    }    
    return _persistentStoreCoordinator;
}

- (void)add_iCloudPersistentStore
{
    NSError *error = nil;
    if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType
                                               configuration:nil
                                                         URL:[self get_iCloudStoreURL]
                                                     options:[self iCloudPersistentStoreOptions]
                                                       error:&error]) {
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
    }
}

- (NSDictionary *)iCloudPersistentStoreOptions
{
    return @{NSPersistentStoreUbiquitousContentNameKey: @"myAppStore",
             NSMigratePersistentStoresAutomaticallyOption : @YES,
             NSInferMappingModelAutomaticallyOption : @YES};
}

有趣的事情:如果我在检测到第一次启动后注释掉[self initializeSeedData],则执行添加数据的“安全捕获”,并创建种子数据就好了!我能想到的唯一不同之处在于我首先在托管对象上下文中执行fetchRequest ...不知何故,_managedObjectContext在执行fetch时被实例化,并且仍然围绕[self initializeSedData]。为什么会这样?

0 个答案:

没有答案