Есть ли более быстрый способ проверить, существуют ли тысячи элементов NSManagedObject? - PullRequest
0 голосов
/ 07 декабря 2011

Я буду использовать пример клиента Google Reader здесь, так как это то, что я на самом деле делаю ...

Я извлекаю (возможно, тысячи) элементов из учетной записи Google Reader, и мне интересно, есть ли более быстрый способ проверки наличия у меня элемента (NSManagedObject) в хранилище данных. Google Reader присваивает каждому элементу уникальный идентификатор строки, который я храню в своих NSManagedObjects. Вот урезанные основы того, что я делаю при импорте. Обратите внимание, что я использую фоновые темы, но для ясности я их здесь удалил.

Могу ли я сделать это более эффективно?

- (void)importBatchOfItems:(NSArray *)itemsFromGoogleReader isLastBatch:(BOOL)isLastBatch {
  for (NSDictionary *item in *itemsFromGoogleReader) {
    NSManagedObject *feedItem = [self feedItemWithId:[item valueForKey:@"GoogleReaderItemID"]];
    if (feedItem == nil) {
      feedItem = [self insertFeedItem];
    }

    // ... do some stuff with feedItem
  }

  BOOL saveIntervalElapsed = (([NSDate timeIntervalSinceReferenceDate] - self.lastBatchSave) >= kBatchSaveInterval);

  if (saveIntervalElapsed || isLastBatch) {
    [self saveContext];
  }
}

- (NSManagedObject *)feedItemWithId:(NSString *)itemId {
  NSPredicate *predicate = [NSPredicate predicateWithFormat:@"id = %@", itemId];

  [self.uniqueItemFetchRequest setPredicate:predicate];
  NSArray *items = [self.managedObjectContext executeFetchRequest:self.uniqueItemFetchRequest error:nil];

  if ([items count] > 0) {
    return [items objectAtIndex:0];
  } else {
    return nil;
  }
}

Ответы [ 2 ]

1 голос
/ 07 декабря 2011

Посмотрите на документы Apple: Эффективный импорт данных У них есть несколько различных способов импорта данных для различных сценариев с фрагментами кода.

1 голос
/ 07 декабря 2011

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

- (NSManagedObject *)feedItemWithId:(NSString *)itemId {
  NSArray *fetchedObjects; // Assume this has already been generated

   NSUInteger i = [array indexOfObjectPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) {
     if ([idx id] = itemID)            
       return YES;
     else
       return NO;
    }];

  if (i != NSNotFound)
    return [array objectAtIndex:i];
  else
    return nil;
}

Этот код был написан на месте, поэтому он может работать не так, как написано. Также, конечно, есть умные способы ускорить это, но, как показано, он должен работать значительно быстрее, чем отдельные запросы на выборку.

...