核心数据无法保存在分发版本中

时间:2015-05-26 18:39:32

标签: ios core-data nsmanagedobjectcontext testflight

我有一个非常奇怪的问题,其中Core Data在开发(调试)版本中运行良好,但是在通过TestFlight分布的分发(发布)版本中,我的NSManagedObjectContext对象无法正确保存。

我正在观察两个问题:

  • NSManagedObjectContextDidSaveNotification在保存上下文时不会被发送。
  • 数据在发布之间不会持续存在。

在分发版本中可能导致此问题的原因是什么?据我所知,配置文件不会影响核心数据。

这是我的核心数据堆栈的两个相关功能:

- (void)initializeCoreData
{
    NSLog(@"%s", __FUNCTION__);

    if ([self managedObjectContext]) return;

    NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"XXX" withExtension:@"momd"];
    NSManagedObjectModel *mom = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
    NSAssert(mom, @"%@:%@ No model to generate a store from", [self class], NSStringFromSelector(_cmd));

    NSPersistentStoreCoordinator *coordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:mom];
    NSAssert(coordinator, @"Failed to initialize coordinator");

    self.privateContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
    self.privateContext.persistentStoreCoordinator = coordinator;

    self.managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
    self.managedObjectContext.parentContext = self.privateContext;



    // Persistence store
    NSMutableDictionary *options = [NSMutableDictionary dictionary];
    options[NSMigratePersistentStoresAutomaticallyOption] = @YES;
    options[NSInferMappingModelAutomaticallyOption] = @YES;
//  options[NSSQLitePragmasOption] = @{ @"journal_mode":@"DELETE" };

    NSURL *documentsURL = [[NSFileManager.defaultManager URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
    // TODO: use real store url
    NSURL *storeURL = [documentsURL URLByAppendingPathComponent:@"Data2.sqlite"];

    NSError *error = nil;
    NSAssert([coordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&error], @"Error initializing PSC: %@\n%@", [error localizedDescription], [error userInfo]);


}

- (void)save;
{
    if (![[self privateContext] hasChanges] && ![[self managedObjectContext] hasChanges]) return;

    [[self managedObjectContext] performBlockAndWait:^{
        NSError *error = nil;

        NSAssert([[self managedObjectContext] save:&error], @"Failed to save main context: %@\n%@", [error localizedDescription], [error userInfo]);

        [[self privateContext] performBlock:^{
            NSError *privateError = nil;
            NSAssert([[self privateContext] save:&privateError], @"Error saving private context: %@\n%@", [privateError localizedDescription], [privateError userInfo]);
        }];
    }];
}

有什么想法吗?

更新:我尝试启动调试版本并在Core Data数据库中存储内容并在启动之间保持良好状态,然后部署版本构建而不删除应用程序以保持数据和数据库似乎为空,然后部署调试版本再次和现有数据库加载正常。因此,由于某种原因,发布版本似乎存在访问数据库文件的问题。有什么想法会发生这种情况吗?

1 个答案:

答案 0 :(得分:4)

NSAssert通常不会在发布版本中运行,因为NS_BLOCK_ASSERTIONS被定义为标准Xcode模板的一部分。或者来自文档

  

重要事项请勿在条件下调用带副作用的功能   这个宏的参数。在何时评估条件参数   断言被禁用,所以如果你调用带副作用的函数,   在a中构建项目时,可能永远不会调用这些函数   非调试配置。

基本上不要在Assert中做你关心的事情。它是一个调试测试。你真的希望在这里更温和一点,软失败。

if([[self managedObjectContext] save:&error] == NO){ 
    NSLog(@"Failed to save main context: %@\n%@", [error localizedDescription], [error userInfo]);
}
else {
    [[self privateContext] performBlock:^{
        NSError *privateError = nil;
        if([[self privateContext] save:&privateError] == NO){ 
            NSLog(@"Error saving private context: %@\n%@", [privateError localizedDescription], [privateError userInfo]);
        }
    }];
}