我目前正在开发一款使用Core Data的应用。我正在使用两个商店/配置,一个用于静态内容,一个用于用户内容。偶尔在启动时我会遇到一个崩溃说:“不能两次添加同一个商店”。我无法跟踪它或经常重复它,所以我想知道是否有人可以提出任何见解?这只是一个在发布时会消失的开发错误(不太可能,我知道)。您可以在下面的代码中看到创建持久存储的错误吗?
另一件值得一提的事情是,我将所有核心数据访问代码都包含在单例类中。我想,两个线程可能会非常接近地访问managedObjectContext
,导致几乎同时访问persistentStoreCoordinator
?
注意:
sharedPaths
是一个短路径名称数组,例如。 @"Data_Static", @"Data_User"
sharedConfigurations
是一个配置名称数组,例如。 @"Static", @"User"
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
if (_persistentStoreCoordinator != nil) {
return _persistentStoreCoordinator;
}
NSString* documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
NSFileManager* fileManager = [NSFileManager defaultManager];
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption, [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];
_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: [self managedObjectModel]];
//load each store/configuration
for(int i=0; i<[sharedPaths count]; i++) {
NSString* path = [sharedPaths objectAtIndex:i];
NSString* configuration = nil;
if([sharedConfigurations count] > 0) {
configuration = [sharedConfigurations objectAtIndex:i];
}
NSString* storePath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.sqlite", path]];
//if the store doesn't exist, copy over the default store
if(![fileManager fileExistsAtPath:storePath]) {
NSString* defaultStorePath = [[NSBundle mainBundle] pathForResource:path ofType:@"sqlite"];
if(defaultStorePath) {
[fileManager copyItemAtPath:defaultStorePath toPath:storePath error:NULL];
}
}
NSURL* storeURL = [NSURL fileURLWithPath:storePath];
NSError* error = nil;
if(![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:configuration URL:storeURL options:options error:&error]) {
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
exit(-1);
}
}
return _persistentStoreCoordinator;
}
答案 0 :(得分:14)
如果您认为这是一个线程问题,请将其置于同步块中:
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
@synchronized(self) {
if (_persistentStoreCoordinator != nil) {
return _persistentStoreCoordinator;
}
...
}
}
这将阻止两个线程同时运行代码。
(您可能需要将此模式添加到同时不能由不同线程运行的任何其他方法。)