向Core Data添加唯一对象

Dim*_*tri 10 iphone core-data objective-c

我正在开发一个从数据库中获取大量对象的iPhone应用程序.我想使用Core Data存储这些内容,但我的关系存在问题.

详细信息包含任意数量的POI(兴趣点).当我从服务器获取一组POI时,它们包含一个详细ID.为了将POI与Detail(通过ID)相关联,我的过程如下:查询ManagedObjectContext以获取detailID.如果存在该详细信息,请将poi添加到其中.如果没有,则创建详细信息(它具有将懒惰填充的其他属性).

这个问题是性能问题.对Core Data执行常量查询的速度很慢,因为所涉及的多个关系,添加150个POI的列表需要一分钟.

在我的旧模型中,在Core Data(各种NSDictionary缓存对象)之前,这个过程非常快(在字典中查找一个键,然后在它不存在时创建它)

我有更多的关系,而不仅仅是这一个,但几乎每个人都必须做这个检查(有些是很多,他们有一个真正的问题).

有没有人对我如何帮助这个有任何建议?我可以执行更少的查询(通过搜索许多不同的ID),但我不确定这将有多大帮助.

一些代码:

        POI *poi = [NSEntityDescription
                insertNewObjectForEntityForName:@"POI"
                inManagedObjectContext:[(AppDelegate*)[UIApplication sharedApplication].delegate managedObjectContext]];

    poi.POIid = [attributeDict objectForKey:kAttributeID];
    poi.detailId = [attributeDict objectForKey:kAttributeDetailID];
    Detail *detail = [self findDetailForID:poi.POIid];
    if(detail == nil)
    {
        detail = [NSEntityDescription
                    insertNewObjectForEntityForName:@"Detail"
                    inManagedObjectContext:[(AppDelegate*)[UIApplication sharedApplication].delegate managedObjectContext]];
        detail.title = poi.POIid;
        detail.subtitle = @"";
        detail.detailType = [attributeDict objectForKey:kAttributeType];
    }





-(Detail*)findDetailForID:(NSString*)detailID {
NSManagedObjectContext *moc = [[UIApplication sharedApplication].delegate managedObjectContext];
NSEntityDescription *entityDescription = [NSEntityDescription
                                          entityForName:@"Detail" inManagedObjectContext:moc];
NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease];
[request setEntity:entityDescription];

NSPredicate *predicate = [NSPredicate predicateWithFormat:
                          @"detailid == %@", detailID];
[request setPredicate:predicate];
NSLog(@"%@", [predicate description]);

NSError *error;
NSArray *array = [moc executeFetchRequest:request error:&error];
if (array == nil || [array count] != 1)
{
        // Deal with error...
    return nil;
}
return [array objectAtIndex:0];
}
Run Code Online (Sandbox Code Playgroud)

ma1*_*w28 6

在Xcode 核心数据编程指南中标题为"核心数据性能"的页面上查看标题为"批处理错误"的部分,Norman在其答案中链接了该指南.

只有那些获取其managedObjects ID是IN一个集合(NSSet,NSArray,NSDictionary服务器返回的对象的ID的)可能会更加高效.

NSSet *oids = [[NSSet alloc] initWithObjects:@"oid1", @"oid2", ..., nil];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"oid IN %@", oids];
[oids release];
Run Code Online (Sandbox Code Playgroud)

更新:我将这个技巧用于acani用户视图的解决方案.基本上,下载后用户的JSON响应,iPhone使用的流行的开源JSON框架解析响应到NSArrayNSDictionary对象,每个对象表示用户.然后,它创建了一个NSArray他们的uid并在Core Data上进行批量获取,以查看它们中是否已存在任何这些.如果没有,它会插入它.如果是这样,只有当它们的updated属性早于服务器的属性时,它才会更新那些存在的属性.


小智 3

此页面提供了一些有关优化性能的帮助: http://developer.apple.com/documentation/Cocoa/Conceptual/CoreData/Articles/cdPerformance.html#//apple_ref/doc/uid/TP40003468-SW1

虽然效率不是很高,但为什么不直接使用 NSDictionary 在内存中构建它们呢?将 Core Data 中的所有内容读取到 NSDictionary 中,然后合并到数据中,替换 Core Data 中的所有内容。