使用PersistentStoreCoodinator管理多个NSPersistentStores

时间:2012-05-09 12:31:34

标签: iphone ios core-data persistence

我正在尝试使用NSPersistentStoreCoordinator来管理多个持久性存储的删除和插入。到目前为止,我已经设法用两个商店配置PSC,我已经能够通过指定其索引来删除任一商店。

喜欢这个......

NSPersistentStore *store = [[self.persistentStoreCoordinator persistentStores] objectAtIndex:0];

        if (![self.persistentStoreCoordinator removePersistentStore:store error:&error]) {

            NSLog(@"Unresolved error %@, %@", error, [error userInfo]);

            abort();

        }

        [[NSFileManager defaultManager] removeItemAtURL:store.URL error:&error];

但是我发现当我将商店添加回PSC时,索引值不正确,并且无法使用现有的类方法指定。这样做的结果是新数据被下载并添加到错误的商店。

有没有人对如何做到这一点有任何建议?

背景(已更新)

使用两个持久存储的原因是我可以为将通过网络下载的两个xml文档指定一个唯一的存储。由于这两个文件都比较大,我希望减少网络流量。因此,检查是否已修改任一文件。如果有,则删除相应的持久存储并添加新存储。就在这时,问题就开始了。添加新商店始终将其添加到持久存储阵列的末尾。当将数据与MOC合并时,这似乎会在商店中造成不匹配。

代码 这是我到目前为止尝试删除和添加持久存储的内容,但新数据被添加到错误的商店。

static NSString * const kLastDateStoreUpdateKey = @"eventLastStoreUpdateKey";

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {

NSString *last_modified = [NSString stringWithFormat:@"%@",[[(NSHTTPURLResponse *)response allHeaderFields] objectForKey:@"Last-Modified"]];

NSDateFormatter *dFormatter = [[NSDateFormatter alloc] init];
[dFormatter setDateFormat:@"EEE, dd MMM yyyy HH:mm:ss zzz"];
[dFormatter setLocale:[[NSLocale alloc] initWithLocaleIdentifier:@"en_GB"]];
[dFormatter setTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"GMT"]];

dateModified = [dFormatter dateFromString:last_modified];
NSDate *previousDate = [[NSUserDefaults standardUserDefaults] objectForKey:kLastDateStoreUpdateKey];

if (!previousDate || [previousDate compare:dateModified] != NSOrderedSame) {

    [self.managedObjectContext lock];
    [self.managedObjectContext reset];


    if ([[NSFileManager defaultManager] fileExistsAtPath:self.persistentStorePath]) {
        NSError *error = nil;

        NSArray *stores = [self.persistentStoreCoordinator persistentStores];
        NSURL *storeUrls = [NSURL fileURLWithPath:persistentStorePath];
        for (NSPersistentStore *store in stores){

            if ([[store.URL absoluteURL] isEqual:[storeUrls absoluteURL]]) {
                if (![self.persistentStoreCoordinator removePersistentStore:store error:&error]) {
                    NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
                    abort();
                }
                [[NSFileManager defaultManager] removeItemAtURL:store.URL error:&error];
                NSLog(@"Check store removed %@", [self.persistentStoreCoordinator persistentStores]);
            }
        }
    }

   NSURL *storeUrl = [NSURL fileURLWithPath:persistentStorePath];
    NSError *error = nil;
    [self.persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:nil error:&error];
    if (error) {
        NSLog(@"event error %@ %@",error, [[self.persistentStoreCoordinator persistentStores] objectAtIndex:0]);
    }
    NSLog(@"Check store added %@",self.persistentStoreCoordinator.persistentStores);

    [self.managedObjectContext unlock];

}else {
    [self cancelDownload];
    NSLog(@"event cancel %@ %@ %@",previousDate, dateModified, [self.persistentStoreCoordinator persistentStores]);
}
}

解决 正如亨特在下面指出的那样,我的PSC配置设置为零。因此,数据未添加到每个持久存储中。当我在核心数据模型中创建配置并以相关实体为目标时,我将PSC设置为具有该配置。然后按预期工作。见下文。

   NSURL *storeUrl = [NSURL fileURLWithPath:persistentStorePath];
NSError *error = nil;
[self.persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:@"ConfigEvent" URL:storeUrl options:nil error:&error];
if (error) {
    NSLog(@"event error %@ %@",error, [[self.persistentStoreCoordinator persistentStores] objectAtIndex:0]);
}
NSLog(@"Check store added %@",self.persistentStoreCoordinator.persistentStores);

2 个答案:

答案 0 :(得分:2)

如果你真的需要两个商店[我无法从你的解释中判断出这是否真的是最好的方式],你可能想通过属性或ivar引用它们而不是依赖于数组。

或者,您可以遍历PSC的商店阵列,并通过检查URL来识别每个商店。

<强>更新

如果您在将不同NSPersistentStores中的特定数据存储时遇到问题,请查看核心数据配置。这允许您告诉Core Data将特定实体放在特定的持久存储中。

您可以在模型中指定配置以及添加持久存储时的配置。更多信息:https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CoreData/Articles/cdMOM.html

答案 1 :(得分:0)

您应该能够使用一个持久性存储协调器和两个托管对象上下文来实现此目的。如果您遇到损害性能的锁定,则只需要考虑两个持久存储协调器的复杂性。

记住:最简单的可能事(tm)