Objective c 如何高效地获取托管对象&;按键属性作为字典索引?
所以,我有一个应用程序,我正在从web服务导入一些数据,并更新我的本地模型以匹配。web服务中的实体具有唯一标识属性,我正在使用该属性来确定是创建新的本地对象,还是获取并更新现有对象 我知道我不想循环输入并运行Objective c 如何高效地获取托管对象&;按键属性作为字典索引?,objective-c,core-data,nsfetchrequest,Objective C,Core Data,Nsfetchrequest,所以,我有一个应用程序,我正在从web服务导入一些数据,并更新我的本地模型以匹配。web服务中的实体具有唯一标识属性,我正在使用该属性来确定是创建新的本地对象,还是获取并更新现有对象 我知道我不想循环输入并运行NSFetchRequest搜索每个项目的唯一ID的匹配项,因为fetch请求很昂贵。相反,我聚合了输入中的所有uniqueid(使用-[NSArray valueForKey:)并使用IN谓词获取所有可能存在的对象 然后,我循环输入——对于每个项目,我检查我刚才做的获取是否包含具有匹配唯
NSFetchRequest
搜索每个项目的唯一ID的匹配项,因为fetch请求很昂贵。相反,我聚合了输入中的所有uniqueid(使用-[NSArray valueForKey:
)并使用IN谓词获取所有可能存在的对象
然后,我循环输入——对于每个项目,我检查我刚才做的获取是否包含具有匹配唯一ID的对象。如果包含,我用输入中的新值更新该对象;否则,我将创建一个新对象
我不知道如何有效地进行匹配。fetch请求为我获取一个数组,因此我需要搜索它以找到与当前输入项的uniqueID匹配的对象。现在我正在使用-[NSArray filteredarrayingpredicate:
。。。因此,我为每个导入的项再次搜索数组(查找我知道在其中的对象)
更简洁有效的方法似乎是将获取请求结果作为字典,使用唯一ID(即在谓词中搜索的属性)作为键,相应的NSManagedObjects作为值。我可以从结果数组设置这样一个字典,但这也需要重复搜索结果数组
如果工具箱里有这样的东西,我还没找到。任何人都能找到一个好方法吗?好的,您可以使用NSDictionary而不是uniqueID作为键值 裸骨起点可能如下所示:
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
}
NSArray*remoteObjects=//按remotePrimarKey排序的字典数组
NSArray*localObjects=//使用[NSPredicate predicateWithFormat:@“%@”,remoteKeys]按remotePrimaryKey排序;
NSInteger localIndex=0;
NSInteger localCount=[localObjects count];
MyManagedObject*本地对象;
for(远程对象中的NSDictionary*远程对象){
localObject=nil;
如果(localIndex
有很多东西你可以改变和优化,但这是我能在浏览器中写的最清楚的了
用通俗易懂的英语
设置
- 获取按remotePrimaryKey排序并限制为远程数组中的键的本地对象
- 确保远程数组按相同的remotePrimaryKey排序
- 一次通过一个对象单步执行远程阵列
- 如果有一个本地对象,那么
- 递增本地数组的索引变量
- 配置此本地返回的对象
- 如果没有找到本地对象
- 创建一个新对象
- 配置这个新的本地对象
- 如果有一个本地对象,那么
- 读入远程对象(字典数组)
- 从中提取一个uniqueid数组(使用
作为从每个字典的valueForKey:
循环并填充数组的缩写)objectForKey:
- 使用所述数组和IN谓词获取可能存在的本地对象
- 通过在结果数组上使用
获取与获取结果相对应的uniqueid数组valueForKey:
- 使用
+[NSDictionary dictionary WithObjects:forKeys://code>获取将UniqueID映射到本地NSManagedObjects的字典
- 循环访问远程对象,查询该字典以确定每个对象是否有需要更新的相应本地对象,或者我们需要为其创建新的本地对象 在(简化)代码中:
- 好吧,我现在觉得自己很笨。我太专注于使用我已经拥有(并在我的获取请求中使用)的uniqueid数组,以至于我忘记了我可以向后工作
因此,以下是总体概述:
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
}
}