Вопрос

I have a method to create managed objects (IntersectionObject) each with three properties. These three properties are managed objects themselves.

PropertyObject1, PropertyObject2, and PropertyObject3 each has about 20 different possibilities.

An IntersectionObject is essentially a combination of a particular PropertyObject1, PropertyObject2, and PropertyObject3.

There are about 1200 IntersectionObjects and to create them I am using a fetch request to retrieve and set the the correct PropertyObject:

- (PropertyObject1 *)fetchedPropertyObject1FromID: (NSNumber *)propertyObjectID {

    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"PropertyObject1"  inManagedObjectContext:[self managedObjectContext]];
    [fetchRequest setEntity:entity];

    NSError *error = nil;
    NSArray *fetchedObjects = [[self managedObjectContext] executeFetchRequest:fetchRequest error:&error];
    if (fetchedObjects == nil) {
        NSLog(@"error fetching PropertyObject from ID, error:%@", error);
    return nil;
    }

    for (PropertyObject1 *object in fetchedObjects) {

        if (object.propertyObjectID.longValue == propertyObjectID.longValue) {
        return object;
        }
    }

    return nil;

}

I am finding that repeating this fetch three times for each of the 1200 IntersectionObjects takes about 2 seconds, and is too slow. Is there a faster way to do this?

EDIT: the accepted answer has the solution that I used in the comments below it. It turns out simply mapping the PropertyObjects to a dictionary was the simplest and quickest way to get the associated objects.

Это было полезно?

Решение

If you have the managed object id, use objectWithID: on the MOC.

If you don't, and you're going to be creating a lot of associations in a short space of time, fetch all of the managed objects from the MOC in batches (perhaps 100 items each batch, see fetchBatchSize on NSFetchRequest), create a dictionary mapping your objectID to the managed objects so you can just do a local lookup. Turn each object back into a fault as you process the batch with refreshObject:mergeChanges:.

Другие советы

Use a predicate to do this, also set the fetch limit to 1. This should get your result in a much more optimized fashion:

- (PropertyObject1 *)fetchedPropertyObject1FromID: (NSNumber *)objectID {

    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"PropertyObject1"  inManagedObjectContext:[self managedObjectContext]];
    [fetchRequest setEntity:entity];

    [fetchRequest setPredicate:[NSPredicate predicateWithFormat:@"objectID == %@", objectID]];
    [fetchRequest setFetchLimit:1];


    NSError *error = nil;
    NSArray *fetchedObjects = [[self managedObjectContext] executeFetchRequest:fetchRequest error:&error];
    if (fetchedObjects == nil) {
        NSLog(@"error fetching PropertyObject from ID, error:%@", error);
    return nil;
    }

    if(fetchedObjects.count > 0)
    {
        [return fetchedObjects objectAtIndex:0];
    }
    return nil;

}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top