Patrón de datos básicos: ¿cómo actualizar eficientemente la información local con cambios desde la red?

Tengo una ineficiencia en mi aplicación que me gustaría entender y solucionar.

Mi algoritmo es:

fetch object collection from network
for each object:
  if (corresponding locally stored object not found): -- A
    create object
    if (a nested related object locally not found): -- B
      create a related object

Estoy comprobando las líneas A y B creando una consulta predicada con la clave del objeto relevante que forma parte de mi esquema. Veo que tanto A (siempre) como B (si la ejecución se ramificó en esa parte) generan una selección SQL como:

2010-02-05 01:57:51.092 app[393:207] CoreData: sql: SELECT <a bunch of fields> FROM ZTABLE1 t0 WHERE  t0.ZID = ? 
2010-02-05 01:57:51.097 app[393:207] CoreData: annotation: sql connection fetch time: 0.0046s
2010-02-05 01:57:51.100 app[393:207] CoreData: annotation: total fetch execution time: 0.0074s for 0 rows.
2010-02-05 01:57:51.125 app[393:207] CoreData: sql: SELECT <a bunch of fields> FROM ZTABLE2 t0 WHERE  t0.ZID = ? 
2010-02-05 01:57:51.129 app[393:207] CoreData: annotation: sql connection fetch time: 0.0040s
2010-02-05 01:57:51.132 app[393:207] CoreData: annotation: total fetch execution time: 0.0071s for 0 rows.

0.0071s para una consulta está bien en un dispositivo 3GS, pero si agrega 100 de estos, obtendrá un bloqueador de 700ms.

En mi código, estoy usando un ayudante para hacer estas recuperaciones:

- (MyObject *) myObjectById:(NSNumber *)myObjectId {
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    [fetchRequest setEntity:[self objectEntity]]; // my entity cache    
    [fetchRequest setPredicate:[self objectPredicateById:objectId]]; // predicate cache    
    NSError *error = nil;
    NSArray *fetchedObjects = [moc executeFetchRequest:fetchRequest error:&error];
    if ([fetchedObjects count] == 1) {
        [fetchRequest release];
        return [fetchedObjects objectAtIndex:0];
    }
    [fetchRequest release];
    return nil;
}

MyObject *obj = [self myObjectById];
if (!obj) {
   // [NSEntityDescription insertNewObjectForEntityForName: ... etc
}

Siento que esto está mal y que debería hacer la verificación de otra manera. Solo debe llegar a la base de datos una vez y debe venir de la memoria a partir de entonces, ¿verdad? (El SQL se ejecuta incluso para objetos que sé con certeza que existen localmente y deberían haberse cargado en la memoria con consultas anteriores). Pero, si solo tengo myObjectId de una fuente externa, esto es lo mejor que se me ocurre.

Entonces, tal vez la pregunta sea: si tengo myObjectId (una propiedad Core Data int64 en MyObject), ¿cómo debo verificar correctamente si el objeto local relevante existe en la tienda de CD o no? ¿Precargar todo el conjunto de coincidencias posibles y luego predicar una matriz local?

(Una posible solución es mover esto a un subproceso en segundo plano. Esto estaría bien, excepto que cuando obtengo los cambios del subproceso y hago [moc mergeChangesFromContextDidSaveNotification: aNotification]; (obteniendo objetos modificados del subproceso en segundo plano a modo de notificación), esto todavía bloques.)

Respuestas a la pregunta(6)

Su respuesta a la pregunta