无法两次添加同一商店

Ben*_*ams 2 iphone core-data objective-c

我目前正在开发一个使用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;
Run Code Online (Sandbox Code Playgroud)

}

dea*_*rne 14

如果您认为这是一个线程问题,请将其放入同步块中:

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
    @synchronized(self) {

        if (_persistentStoreCoordinator != nil) {
            return _persistentStoreCoordinator;
        }

        ...

    }
}
Run Code Online (Sandbox Code Playgroud)

这将停止两个线程同时运行代码.

(您可能需要将此模式添加到同时不能由不同线程运行的任何其他方法.)