我试图让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]);
}
}
解决了
正如Hunter在下面指出的那样,我的PSC配置设置为nil。因此,没有将数据添加到每个单独的持久性存储中。当我在核心数据模型中创建配置并定位相关实体时,我将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);
最佳答案
如果您确实需要这两个存储库(从您的解释中我无法确定这是否真的是最好的方法),则可能需要通过属性或ivar来引用它们,而不是依赖数组。
另外,您可以遍历PSC的stores数组,并通过检查URL来识别每个数组。
更新:
如果您在将特定数据存储在不同的NSPersistentStore中时遇到麻烦,请查看核心数据配置。这使您可以告诉Core Data将特定实体放入特定的持久性存储中。
您可以在模型中以及添加持久性存储时指定配置。更多内容:https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CoreData/Articles/cdMOM.html