Tengo un modelo de datos básicos que representan una guía de TV en iOS 4, con 3 clases:Rendimiento: relaciones Core Obtener datos falla después de haber sido asignado
Channel
(BBC 1)Program
(Top Gear)Broadcast
(Top Gear de la BBC 1 el lunes a las 20:00)
tengo cerca de 40 canales, programas 8000 y 6000 las emisiones, y me gustaría afinar el im proceso de puerto para que no demore un minuto en ejecutarse.
La importación de canales y programas es fácil porque estos son objetos independientes. Sin embargo, una transmisión tiene una relación con un canal y con un programa (de 1 a varios), y ambos canales y programas tienen relaciones inversas con las emisiones (de muchos a 1). Para acelerar las cosas, tengo un diccionario en memoria de canales de fallas y programas que solo obtuvieron previamente su identificador de servicio web: creo una transmisión y busco en los dos diccionarios para obtener el canal y el programa correspondientes sin un viaje de ida y vuelta a la base de datos.
Pero cuando asigno un programa o canal a una transmisión, el acceso de relaciones inversas del canal y del programa desencadenan inmediatamente un error de ambos objetos, causando una desaceleración masiva (6000 * 2 solicitudes) y la consiguiente presión de memoria como se muestra en el informe de los fallos de datos básicos. Intenté precargar la relación broadcasts
tanto en canales como en programas, pero la relación aún tiene errores.
¿Tiene alguna idea de por qué se accede a las relaciones inversas y culpan a sus padres? ¿Cómo evito leer en la base de datos cuando guardo una relación?
ACTUALIZACIÓN: Código de ejemplo, mi método de asignación/actualización para una instancia de Broadcast
. La variable dictionary
proviene del servicio web y channels
y programs
contienen los canales de falla y objetos de programas indexados por el identificador del servicio web. La falla ocurre en las líneas self.program = program
y self.channel = channel
.
- (BOOL)assignWithDictionary:(NSDictionary *)dictionary channels:(NSDictionary *)channels programs:(NSDictionary *)programs {
// Add channel relationship
NSNumber *channelIdentifier = [dictionary objectForKey:@"channel_id"];
if (self.channel == nil || ![self.channel.identifier isEqualToNumber:channelIdentifier]) {
Channel *channel = [channels objectForKey:channelIdentifier];
if (channel == nil) {
NSLog(@"Broadcast %@ has invalid channel: %@", identifier, channelIdentifier);
return NO;
}
self.channel = channel;
}
// Same to add a program relationship
// ...
}
y mi petición de recuperación para obtener los canales o programas de la lista:
- (NSDictionary *)itemsForEntity:(NSEntityDescription *)entity {
NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease];
NSError *error = nil;
NSArray *itemsArray = nil;
request.entity = entity;
request.relationshipKeyPathsForPrefetching = [NSArray arrayWithObject:@"broadcasts", nil];
request.propertiesToFetch = [NSArray arrayWithObjects:@"identifier", @"version", nil];
itemsArray = [self.context executeFetchRequest:request error:&error];
NSAssert1(error == nil, @"Could not fetch the items from the database: %@", error);
{
NSMutableDictionary *items = [NSMutableDictionary dictionaryWithCapacity:itemsArray.count];
for (NSManagedObject *item in itemsArray) {
[items setObject:item forKey:[item valueForKey:@"identifier"]];
}
return [NSDictionary dictionaryWithDictionary:items];
}
}
+1, porque una vez tuve un problema muy similar que no pude resolver, finalmente haciendo cosas completamente diferentes. Sin embargo, aún tengo curiosidad sobre lo que pude haber hecho al respecto. – Toastor
¿Cómo es su "programa o canal de difusión" usando solo un "identificador"? Supongo que el "identificador" es un managedObjectID o un URI de la misma? Sugeriría mostrar el código donde haces esto. – TechZen
Obtengo datos de un servicio web que describe las relaciones usando identificadores numéricos, nada que ver con los identificadores de datos centrales (debería haberlo mencionado) – ndfred