简体   繁体   English

iPhone核心数据可以缓存NSManagedObjects吗?

[英]iPhone core data can I cache NSManagedObjects?

I'm running a data model in one of my apps, where an event has an "eventType" relationship defined. 我在其中一个事件中定义了“ eventType”关系的应用程序中运行数据模型。 This allows me to modify the look and feel of multiple events by changing their "eventType" relationship object. 这使我可以通过更改多个事件的“ eventType”关系对象来修改其外观。

The problem that I'm running into is that before I insert an event, I check if a typeRelationship for this object is present with the code below. 我遇到的问题是,在插入事件之前,请检查下面的代码是否存在此对象的typeRelationship。 This takes some time if I need to insert a large number of objects. 如果我需要插入大量对象,则需要一些时间。

Can I cache the results of this fetch request (for example in NSMutableDictionary ) and check that dictionary (local memory) to see if there is an NSManagedObject with the given EventIDEnum ? 我是否可以缓存此获取请求的结果(例如,在NSMutableDictionary )并检查该字典(本地内存)以查看是否存在带有给定EventIDEnumNSManagedObject Can I keep the cache alive forever, or will the underlying objects get "out of date" after a while? 我可以使缓存永远保持活动状态,还是一段时间后基础对象会“过时”?

-(Event*)insertAndReturnNewObjectWithTypeID:(EventIDEnum)eventTypeID date:(NSDate*)date
{

    NSFetchRequest *eventTypesArray = [NSFetchRequest fetchRequestWithEntityName:@"EventType"];
    eventTypesArray.predicate = [NSPredicate predicateWithFormat:@"SELF.id == %d", eventTypeID];
    NSArray *eventTypes = [[DataManager sharedInstance].managedObjectContext executeFetchRequest:eventTypesArray error:nil];

    if(eventTypes.count==0)
    {
        DLog(@"ERROR inserting event with type: %i NOT FOUND",(int)eventTypeID);
        return nil;
    }
    else {

        if(eventTypes.count !=1)
        {
            DLog(@"ERROR found %i events with type %i",eventTypes.count,(int)eventTypeID);
        }

        EventType* eventType = [eventTypes lastObject];

        if(date)
        {
//            DLog(@"Returning object");
            return [self insertAndReturnNewObjectWithEventType:eventType date:date];
        }else {
//            DLog(@"Returning object");
            return [self insertAndReturnNewObjectWithEventType:eventType];
        }



    }
}

Thank you for taking a look at my question! 感谢您看我的问题!

The array of objects returned by a fetch request cannot be cached. 提取请求返回的对象数组无法缓存。 They are only valid as long as the NSManagedObjectContext that was used to query them has not been released. 它们仅在未发布用于查询它们的NSManagedObjectContext时才有效。 The NsManagedObject.objectID and the data you retrieve from the query can be cached and kept for as long as you like. NsManagedObject.objectID和您从查询中检索的数据可以被缓存并保留任意长的时间。 You are probably better off copying the pertinent data and objectIDs into another object you cache and maintain separately from CoreData objects; 您最好将相关的数据和objectID复制到另一个要缓存并与CoreData对象分开维护的对象中; and releasing the core data array that was returned by the fetch request. 并释放获取请求返回的核心数据数组。

The pattern you're using is often referred to as "find or create": look for an object whose uniquing characteristic matches, return it if it exists, create/populate/return it if it didn't exist. 您使用的模式通常被称为“查找或创建”:寻找一个唯一特征匹配的对象,如果存在则返回它,如果不存在则创建/填充/返回它。

One thing you can do to speed this up is to do the uniquing outside of Core Data. 您可以加快速度的一件事是在Core Data之外进行唯一化。 If it's possible based on your data, perhaps you can iterate over your EventIDEnum values, find the unique values you need to have available, and thus reduce the number of fetches you perform. 如果有可能基于您的数据,也许您可​​以遍历EventIDEnum值,找到所需的唯一值,从而减少执行的访存次数。 You'll only search once for each EventIDEnum. 每个EventIDEnum仅搜索一次。 As long as you're working within one thread/context, you can cache those. 只要您在一个线程/上下文中工作,就可以缓存它们。

When I'm writing this kind of code, I find it helpful to pass in the NSManagedObjectContext as a parameter. 当我编写此类代码时,我发现将NSManagedObjectContext作为参数传递很有帮助。 That allows me to use the find-or-create or bulk insert methods anywhere, either on the main thread or within a private queue/context. 这使我可以在主线程上或专用队列/上下文中的任何位置使用查找或创建或批量插入方法。 That would take the place of your [[DataManager sharedInstance] managedObjecContext] call. 那将代替您的[[DataManager sharedInstance] managedObjecContext]调用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM