Производительность: отношения Core Data нарушаются после назначения

У меня есть модель Core Data, представляющая телегид на iOS 4+, с 3 классами:

  • Канал (BBC 1)
  • Программа (Top Gear)
  • Трансляция (Top Gear на BBC 1 в понедельник в 20:00)

У меня около 40 каналов, 8000 программ и 6000 трансляций, и я хотел бы точно настроить процесс импорта, чтобы он не занимал до минуты.

Импорт каналов и программ прост, потому что это независимые объекты. Однако широковещательная передача имеет отношение к каналу и программе (1-ко-многим), а каналы и программы имеют обратную связь с широковещательными передачами (многие-к-1). Чтобы ускорить процесс, у меня есть словарь в памяти каналов ошибок и программ, для которых предварительно загружен только их идентификатор веб-службы: я создаю широковещательную рассылку и просматриваю оба словаря, чтобы получить соответствующий канал и программу без обращения к базе данных.

Но когда я назначаю программу или канал для трансляции, доступ к каналу и программе с обратной связью сразу вызывает сбой обоих объектов, вызывая значительное замедление (6000 * 2 запросов) и, как следствие, нехватку памяти, как показано в Отчет Core Data Faults Instruments. Я пробовал предварительно загрузить отношения трансляции на обоих каналах и программах, но отношения все равно нарушаются.

Вы хоть представляете, почему обращаются к обратным отношениям и винят их родителей?Как мне избежать чтения из базы данных при сохранении отношения?

ОБНОВЛЕНИЕ: Пример кода, мой метод назначения / обновления для экземпляра Broadcast . Переменная словаря поступает из веб-службы, а каналы и программы содержат каналы ошибок и программные объекты, индексированные идентификатором веб-службы. Ошибка возникает в строках self.program = program и 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
    // ...
}

И мой запрос на получение каналов или списка программ:

- (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];
    }
}
6
задан ndfred 12 August 2011 в 15:39
поделиться