Cocoa 如何获取核心数据以使用自己的NSManagedObjectID URI方案?
我正在编写一个连接到数据库以获取数据的应用程序。由于抓取是昂贵的,而且数据通常是不变的,所以我使用CoreData来缓存结果,这样我就可以进行快速的本地查询 从数据库中,对于每种类型,都有一个保证唯一的字符串属性。事实上,数据库有一个URI方案,它是每个项目的唯一地址 URL方案非常基本,大致如下: ngaobject://// 我也希望能在CoreData中使用它。我创建了一个从CoreData存储中获取单个项的方法:Cocoa 如何获取核心数据以使用自己的NSManagedObjectID URI方案?,cocoa,cocoa-touch,core-data,Cocoa,Cocoa Touch,Core Data,我正在编写一个连接到数据库以获取数据的应用程序。由于抓取是昂贵的,而且数据通常是不变的,所以我使用CoreData来缓存结果,这样我就可以进行快速的本地查询 从数据库中,对于每种类型,都有一个保证唯一的字符串属性。事实上,数据库有一个URI方案,它是每个项目的唯一地址 URL方案非常基本,大致如下: ngaobject://// 我也希望能在CoreData中使用它。我创建了一个从CoreData存储中获取单个项的方法: -(NSFetchRequest*)fetchRequestForType
-(NSFetchRequest*)fetchRequestForType:(NSString*)typeName identifier:(NSString*)identifier
{
NSFetchRequest * fetchRequest = [self fetchRequestForType:typeName];
[fetchRequest setFetchLimit:1];
NSString * identifierProperty = [self identifierPropertyNameForObjectType:typeName];
NSPredicate * predicate = [NSPredicate predicateWithFormat:@"%K == %@", identifierProperty, identifier];
[fetchRequest setPredicate:predicate];
return fetchRequest;
}
-(NGAObject*)objectWithType:(NSString*)typeName
identifier:(NSString*)identifier
{
// First try to retrieve it from the cache
NSAssert1( (identifier != nil), @"Request to create nil-name object of type %@", typeName );
NSFetchRequest * fetchRequest = [self fetchRequestForType:typeName identifier:identifier];
if ( !fetchRequest )
return nil;
NSError * error = nil;
NSArray * fetchResults = [[self managedObjectContext] executeFetchRequest:fetchRequest error:&error];
if ( !fetchResults )
{
NSLog(@"%@", error);
[NSApp presentError:error];
return nil;
}
if ( [fetchResults count] )
return [fetchResults objectAtIndex:0];
return nil;
}
当我从服务器检索一个项目时,我想首先在缓存中获取对它的引用,如果它在那里,则更新它。如果不是,创建一个新的
因为我要从服务器上取回数千个对象,所以对我知道唯一ID的单个对象执行抓取操作会使我的机器陷入爬行状态
相反,我所做的是预加载一个类型的所有对象,然后创建一个标识符的字典->对象,然后通过在字典中运行它来处理该类型的数千个对象。这很好,但很尴尬
我是否可以编写一个方法,在不执行冗长的获取请求的情况下,使用类型/标识符组合并从CoreData获取单个对象
如果我能让CoreData使用我自己的URI规范,似乎有一个解决方案。然后,我可以在持久存储协调器上调用-(NSManagedObjectID*)managedobjectdforurirepresentation:(NSURL*)url
所以,问题是,如何让CoreData使用我的URI方案?如何使CoreData使用自己的唯一标识符?在CoreData designer中,用于唯一ID查找的所有字段都标记为“索引”吗?如果这样做了,那么CoreData回迁就不会太长。您不能让核心数据使用自定义URI方案。URI方案被硬编码到核心数据中,使得URI可以被解码以定位特定硬件上特定应用程序中特定存储中的特定数据。如果URI是可定制的,那么系统就会崩溃 奇异地抓取对象是让你痛苦的。相反,您需要批量获取customID与服务器提供的匹配的所有对象。最简单的方法是在谓词运算符中使用
:
NSArray *customIDs=//... array of customIDs provided by server
NSPredicate *p;
p=[NSPredicate predicateWithFormat: @"customIdAtrribute IN %@", customIDs];
这将返回您可以忽略的所有现有对象
或者,你可以
通过将fetch的propertiesToFetch
设置为customID
属性,仅对customID
属性执行fetch李>
将获取结果类型设置为dictionary李>
使用上面的谓词李>
您将得到一个一键字典数组,返回的每个值都是customID李>
将字典转换为值数组,例如cachedIDs
将上面的customid
转换为可变数组李>
使用谓词,@“NOT(SELF-IN%@)”,cachedIDs“
过滤后的customID
数组现在只包含未缓存在核心数据中的customID值
您只能为新ID创建托管对象
(如果您与筛选器谓词不相似,则使用该谓词。)
…其输出:
f=(
1,
2,
3,
4
)
不,不是。这是一个很好的建议,我会尝试一下。不过,为了回答这个问题,有没有办法完成我的计划?不确定,这里的另一个问题似乎不建议。一般来说,如果你发现自己试图破解CoreData如何工作的内部机制,那么你可能正在做一些出了问题。在这种情况下,我很确定最好的解决方案就是使用表索引,这将是建议的CoreData方法(实际上这将适用于任何RDBMS)
f=(
1,
2,
3,
4
)