Использование базовых данных с хранилищем sqlite на iPhone .... У меня есть набор сущностей с изображениями комиксов, каждая со строкой, которая включает в себя номер комикса #, например: image.imageTitle = @"Issue 12: Special Edition";
Часть пользовательского интерфейса позволяет пользователю ввести номер проблемы, чтобы перейти к следующей проблеме. Мой исходный код для этого был sloooooooow, потому что imageAtIndex:
запрашивает базовые данные для одного объекта за один раз. Более нескольких сотен проблем может пройти более 40 секунд, чтобы пройти первый цикл!
Медленный код:
// Seek forward from the next page to the right
for (i = currentPage + 1; i < [self numberOfPages]; i++) {
iterationString = [[self imageAtIndex:i] imageTitle];
iterationNumber = [[iterationString stringByTrimmingCharactersInSet:nonDigits] intValue];
if (issueNumber == iterationNumber) {
keepLooking = NO;
break;
}
}
// If nothing was found to the right, seek forward from 0 to the current page
if (i == [self numberOfPages] && keepLooking) {
for (i = 0 ; i < currentPage; i++) {
iterationString = [[self imageAtIndex:i] imageTitle];
iterationNumber = [[iterationString stringByTrimmingCharactersInSet:nonDigits] intValue];
if (issueNumber == iterationNumber) {
keepLooking = NO;
break;
}
}
}
Надеясь на гораздо более эффективное решение, я решил попытаться сделать прямой запрос к Базовым данным следующим образом:
NSString *issueNumber = @"12";
NSString *issueWithWordBoundaries = [NSString stringWithFormat:@"\\b%@\\b",issueNumber];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(groupID == %@) AND (imageTitle CONTAINS %@)", groupID, issueWithWordBoundaries];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"CBImage" inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
[fetchRequest setPredicate:predicate];
[fetchRequest setIncludesSubentities:NO]; // Not sure if this is needed, but just in case....
// Execute the fetch
NSError *error = nil;
NSArray *fetchedObjects = [managedObjectContext executeFetchRequest:fetchRequest error:&error];
// [fetchedImages count] == 0
Между Руководством по программированию предикатов и Спецификациями регулярного выражения ICU я полагал, что \ b поможет предотвратить поиск 12, возвращающий 120, 121, 122 и т. Д. Вместо этого он вообще ничего не возвращает из магазина!
С другой стороны, если я опускаю границы слова и вместо этого ищу stringWithFormat:@"%@",issueNumber
, я получаю десятки возвращаемых управляемых объектов, от 12 до 129 до 412.
Мое лучшее предположение на данный момент заключается в том, что я столкнулся с одним из ограничений и ограничений Core Data . Если нет, что я делаю не так? Если да, есть ли обходной путь, который предлагает как точное совпадение , так и скорость одной выборки?