所以,我有一个应用程序,我从Web服务导入一些数据并更新我的本地模型以匹配。来自Web服务的实体具有唯一标识属性,我正在使用它来确定是创建新的本地对象还是获取和更新现有对象。
我知道我不想循环输入并运行NSFetchRequest
搜索每个项目的uniqueID匹配,因为获取请求很昂贵。相反,我汇总输入中的所有uniqueID(使用-[NSArray valueForKey:]
轻松完成)并使用IN谓词获取所有可能存在的对象。
然后,我遍历输入 - 对于每个项目,我检查我刚刚进行的提取是否包含具有匹配唯一ID的对象。如果是,我用输入中的新值更新该对象;否则我会创建一个新对象。
这是匹配,我不知道如何有效地做。获取请求获取一个数组,因此我需要搜索它以找到与当前输入项的唯一ID匹配的对象。现在我正在使用-[NSArray filteredArrayUsingPredicate:]
...所以我为每个导入的项目再次搜索数组(对于我知道的对象)。
似乎更简洁有效的方法是将获取请求结果作为字典,将唯一ID(即在谓词中搜索的属性)作为键,将相应的NSManagedObjects作为值。我可以从结果数组中设置这样的字典,但这也需要重复搜索结果数组。
如果套件提供类似的东西,我找不到多少运气。有人遇到过一个好方法吗?
答案 0 :(得分:0)
除了使用数组之外,您可以使用NSDictionary,而不是使用uniqueID作为键值。
答案 1 :(得分:0)
一个简单的起点可能看起来像:
NSArray *remoteObjects = // Array of dictionaries sorted by remotePrimarKey
NSArray *localObjects = // Sorted by remotePrimaryKey using [NSPredicate predicateWithFormat:@"%@", remoteKeys];
NSInteger localIndex = 0;
NSInteger localCount = [localObjects count];
MyManagedObject *localObject;
for (NSDictionary *remoteObject in remoteObjects) {
localObject = nil;
if (localIndex < localCount) {
localObject = [localObjects objectAtIndex:localIndex];
}
if (<# localObject.primaryKey == remoteObject.primaryKey #>) {
localIndex++;
} else {
localObject = // create new instance of MyManagedObject
}
// Configure localObject here
}
有很多东西你可以改变并优化,但这是我在浏览器中写的最清楚
用简单的英语
设置
<强>过程强>
答案 2 :(得分:0)
好的,我现在感到愚蠢。我非常专注于使用我已经拥有的uniqueID数组(并在我的获取请求中使用),我忘记了我可以向后工作。
所以,这是一般大纲:
读入远程对象(词典数组)。
从中提取一系列uniqueIDs(使用valueForKey:
作为循环并从每个字典objectForKey:
填充数组的简写
使用所述数组和IN谓词来获取可能存在的本地对象。
使用结果数组上的valueForKey:
获取与获取结果相对应的uniqueID数组。
使用+[NSDictionary dictionaryWithObjects:forKeys:]
获取将uniqueID映射到本地NSManagedObjects的字典。
循环访问远程对象,查询该字典以确定每个字体是否具有需要更新的相应本地对象,或者我们需要为其创建新的本地对象。
在(简化)代码中:
NSArray *remoteObjects; // array of dictionaries read in from server
NSArray *remoteIDs = [remoteObjects valueForKey:@"uniqueID"];
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:myEntityName];
request.predicate = [NSPredicate predicateWithFormat:@"uniqueID IN %@", remoteIDs];
NSArray *results = [context executeFetchRequest:request error:NULL];
NSArray *existingIDs = [results valueForKey:@"uniqueID"];
NSDictionary *existingObjects = [NSDictionary dictionaryWithObjects:results forKeys:existingIDs];
for (NSDictionary *remoteObject in remoteObjects) {
MyManagedObject *existingObject = [existingObjects objectForKey:[remoteObject valueForKey:@"uniqueID"]];
if (existingObject) {
// have matching local object already, update it
} else {
// create new local object
}
}