我有一个非常奇怪的问题,其中Core Data在开发(调试)版本中运行良好,但是在通过TestFlight分布的分发(发布)版本中,我的NSManagedObjectContext对象无法正确保存。
我正在观察两个问题:
在分发版本中可能导致此问题的原因是什么?据我所知,配置文件不会影响核心数据。
这是我的核心数据堆栈的两个相关功能:
- (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数据库中存储内容并在启动之间保持良好状态,然后部署版本构建而不删除应用程序以保持数据和数据库似乎为空,然后部署调试版本再次和现有数据库加载正常。因此,由于某种原因,发布版本似乎存在访问数据库文件的问题。有什么想法会发生这种情况吗?
答案 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]);
}
}];
}