我的应用程序最近从只发生在iOS9上的crashlytics中获得了这些崩溃。
致命例外: NSInternalInconsistencyException 此NSPersistentStoreCoordinator没有持久存储(损坏的文件)。它不能执行保存操作。
报告中的最后一个呼吁是
-[NSPersistentStoreCoordinator _coordinator_you_never_successfully_opened_the_database_device_locked:]NSPersistentStoreCoordinator就是这样创建的
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator{
if (_persistentStoreCoordinator != nil) {
return _persistentStoreCoordinator;
}
AppDelegate *delegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
NSURL *storeURL = [[delegate applicationDocumentsDirectory] URLByAppendingPathComponent:@"database.sqlite"];
_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:self.managedObjectModel];
NSError* error = nil;
if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil
URL:storeURL
options:@{NSMigratePersistentStoresAutomaticallyOption:@YES, NSInferMappingModelAutomaticallyOption:@YES} error:&error])
{
NSLog(@"Error adding persistent store. %@, %@", error, error.userInfo);
return nil;
}
return _persistentStoreCoordinator;
}有人知道是什么导致了这些车祸吗?
发布于 2015-10-21 14:28:53
我在iOS9上没有经历过这样的错误。然而,您应该查看您的日志,看看您有哪些错误。您是否可能在PSC创建时遇到“添加持久存储的错误”?
您的方法有一个问题,如果您遇到该错误,随后的调用将返回一个PSC,这个PSC既不是零,也不是正确的设置。
原因是在成功安装_persistentStoreCoordinator之前分配它。因此,如果有任何错误,则返回零,但下次调用该方法时,将返回没有存储的PSC。
无论如何,您应该更改该方法,以便只返回零或完全操作的PSC。
我会把这个方法变成这样的。然而,Note表示,我永远不会构建这样的核心数据堆栈。但是,至少下面的代码将修复您的错误,您可以返回部分组成的PSC。
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator{
if (_persistentStoreCoordinator != nil) {
return _persistentStoreCoordinator;
}
AppDelegate *delegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
NSURL *storeURL = [[delegate applicationDocumentsDirectory]
URLByAppendingPathComponent:@"database.sqlite"];
NSPersistentStoreCoordinator *psc = [[NSPersistentStoreCoordinator alloc]
initWithManagedObjectModel:self.managedObjectModel];
NSError *error = nil;
if (![psc addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil
URL:storeURL
options:@{NSMigratePersistentStoresAutomaticallyOption:@YES,
NSInferMappingModelAutomaticallyOption:@YES}
error:&error]) {
NSLog(@"Error adding persistent store. %@, %@", error, error.userInfo);
} else {
_persistentStoreCoordinator = psc;
}
return _persistentStoreCoordinator;
}编辑
在评论中没有足够的空间回答你的问题,所以我把它放在这里。
@JodyHagins -而且,您提到不会像这样构造堆栈,您能让我知道我的堆栈有什么问题吗?- AWillian
我这么说是因为您发布的代码与默认的Xcode核心数据模板非常相似。您可以调用app委托来获取目录,这表明它不在app委托中,这是很好的。
但是,该方法表明您从"anywhere“访问它,这表明您的堆栈不是以我构建堆栈的方式构建的(特别是因为您还包括迁移选项)。
我不是故意说你做的是错的,只是这不是我会怎么做的。
现在,我会第一个说我所做的就是我所做的.我不认为这是正确的方法..。就按我的方式。事实上,我没有见过其他人真正做我所做的事情(我实际上是子类NSManagedObjectContext,尽管我不介意警告,并且远离那些挑剔的部分)。这本身可能表明,我所做的可能不适合你或其他任何人。但是,我发现它适合我自己,以及我必须实现的非常复杂的应用程序。
那么,我将如何构建一个堆栈呢?
嗯,这比回答要深入得多,所以我会说得很简短。这也取决于哪种类型的堆栈父/子,兄弟姐妹有相同的PSC,表兄弟姐妹有不同的PSC,但相同的商店。
首先,我不提供对模型和协调器的单独访问。您可以轻松地从上下文中访问这些内容,结果通常会导致比其价值更多的问题。
除了测试和简单的例子,我总是异步地创建我的MOC,如下所示.
+ (void)createWithConcurrencyType:(NSManagedObjectContextConcurrencyType)concurrencyType
completion:(void(^)(NSManagedObjectContext *moc, NSError *error))completion;MOM被创建并分配给PSC,PSC被创建并分配给MOC。这种情况是异步发生的,因此打开和初始化的潜在长进程可以在后台线程中完成。完成处理程序是在performBlock中调用的,因此可以干净地使用MOC。这也防止在MOC完全安装和读取之前使用。
即使使用主队列并发类型调用,所有工作都是在后台线程中完成的,因此只在主线程上调用完成。
在创建用于导入和临时目的的相关MOC时,我也使用相同的模式。
发布于 2016-02-16 02:42:44
来自Apple论坛这里的答案也解释了一个可能的原因和解决方案。
原因在于描述符:当设备被锁定时,应用程序试图打开持久存储,代码被数据保护API绊倒。 这就是你在新设备和新iOS版本上遇到的问题,因为新设备足够快地让应用程序在数据保护代码完成转换之前运行。
这类问题的解决办法如下所示
您几乎必须进入启动代码,并重写它,以便检查是否有受保护的数据,然后将核心数据的启动推迟到applicationProtectedDataDidBecomeAvailable。
https://stackoverflow.com/questions/33251528
复制相似问题