Есть ли более эффективный способ памяти для поиска в базе данных Core Data? - PullRequest
0 голосов
/ 16 января 2011

Мне нужно проверить, существует ли в моей базе данных базовых данных объект, полученный из файла CSV с уникальным идентификатором, и этот код я считаю подходящим для этой задачи:

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity;
entity = 
[NSEntityDescription entityForName:@"ICD9"
            inManagedObjectContext:passedContext];
[fetchRequest setEntity:entity];
NSPredicate *pred = [NSPredicate predicateWithFormat:@"uniqueID like %@", uniqueIdentifier];
[fetchRequest setPredicate:pred];
NSError *err;
NSArray* icd9s = [passedContext executeFetchRequest:fetchRequest error:&err];
[fetchRequest release];
if ([icd9s count] > 0) {
    for (int i = 0; i < [icd9s count]; i++) {
        NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];
        NSString *name = [[icd9s objectAtIndex:i] valueForKey:@"uniqueID"];
        if ([name caseInsensitiveCompare:uniqueIdentifier] == NSOrderedSame && name != nil)
        {
            [pool release];
            return [icd9s objectAtIndex:i];
        }
        [pool release];
    }
}
return nil;

После более тщательного тестирования кажется, что этот код ответственен за огромную утечку в приложении, которое я пишу (он падает на 3GS, прежде чем сделать его 20% через 1459 пунктов). Я чувствую, что это не самый эффективный способ сделать это, какие-либо предложения для более эффективного использования памяти? Заранее спасибо!

Ответы [ 2 ]

2 голосов
/ 16 января 2011
  • Не используйте оператор like в предикате запроса.Используйте =.Это должно быть намного быстрее.
  • Вы можете указать регистронезависимость поиска через предикат, используя модификатор [c].
  • Нет необходимости создавать и уничтожать NSAutoreleasePool вкаждая итерация вашего цикла.На самом деле, это, вероятно, вообще не нужно.
  • Вам не нужно выполнять какую-либо проверку внутри цикла for().Вы дублируете работу своего предиката.

Поэтому я бы изменил ваш код на:

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
[fetchRequest setEntity:...];
[fetchRequest setPredicate:[NSPredicate predicateWithFormat:@"uniqueID =[c] %@", uniqueIdentifier]];
NSError *err = nil;
NSArray *icd9s = [passedContext executeFetchRequest:fetchRequest error:&err];
[fetchRequest release];
if (error == nil && [icd9s count] > 0) {
  return [icd9s objectAtIndex:0]; //we know the uniqueID matches, because of the predicate
}
return nil;
1 голос
/ 16 января 2011

Используйте шаблон Leaks в приборах для поиска утечек.Ваш текущий код может быть хорошо, как только вы их исправите.Утечки могут даже быть где-то отличными от кода.

Другие проблемы:

  • Использование быстрого перечисления сделает цикл над массивом (1)быстрее и (2) намного легче читать.
  • Не отправлять release в пул авто-релиза.Если вы когда-нибудь перенесете код на какао, собираемое мусором, пул ничего не сделает.Вместо этого отправьте его drain;в сохраняющем выпуске Какао и в Cocoa Touch это работает так же, как release, а в собираемом мусоре Какао он запускает сборщик мусора, который является самым близким эквивалентом в земле GC для осушения пула.
  • Не повторяйте себя. В настоящее время у вас есть две [pool release]; строки для одного пула, что действительно беспокоит каждого опытного программиста Cocoa и Cocoa Touch.Сохраните результат ваших тестов по имени в логической переменной, затем истощите пул перед условием, а затем условно верните объект.
  • Будьте осторожны с типами переменных.-[NSArray count] возвращает и -[NSArray objectAtIndex:] принимает NSUInteger, а не int.Старайтесь, чтобы все ваши типы совпадали.(Переключение на быстрое перечисление, конечно, решит эту проблему по-другому.)
  • Не скрывать выпуски.Я чуть не обвинил вас в том, что вы пропустили запрос на выборку, а затем заметил, что вы похоронили его в середине кода.Сделайте ваши выпуски заметными, чтобы вы с меньшей вероятностью случайно добавили избыточные (то есть вызывающие сбои).
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...