использование NSPredicate содержит, чтобы найти символы в поле сущности coredata - PullRequest
5 голосов
/ 17 марта 2011

Я пытаюсь найти всех клиентов, которые содержат определенную последовательность букв.Я хочу, чтобы функциональность идентичная NSString rangeofString за исключением регистра.Вот мой метод:

-(NSArray *) db_search: (NSString *) table where: (NSString*) fieldKey contains: (NSString*) value withSortField: (NSString *) sortField{
    NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease];
    NSEntityDescription *entity = [NSEntityDescription entityForName:table inManagedObjectContext:context];
    if (fieldKey != nil){
        NSPredicate *predicate = [NSPredicate
                                  predicateWithFormat:@"(%@ contains[c] %@)",
                                  fieldKey,value];
        [request setPredicate:predicate];
    }
    [request setEntity:entity];

    if (sortField != nil){
        NSSortDescriptor *sortDescriptor = [[[NSSortDescriptor alloc] initWithKey:[self extractSortField:sortField] ascending:[self isAscending:sortField]] autorelease];
        NSArray *sortDescriptors = [[[NSArray alloc] initWithObjects:sortDescriptor, nil] autorelease];
        [request setSortDescriptors:sortDescriptors];
    }

    NSError *error;
    return [context executeFetchRequest:request error:&error];
}

Я вызываю его со следующими значениями:

NSArray * results = [self db_search:@"Customer" where:@"fullname" contains:@"matt" withSortField:nil];

Вместо того, чтобы получить все Маты, Матфея и т. Д., Он зависает, когда я пытаюсь распечататьРезультаты.Я отладил его, и мы даже не вернули пустой NSArray.Я печатаю NSArray на консоль, и я не получаю 0 элементов .. Я просто ничего не получаю.

Я попытался сделать дамп базы данных на консоль, и он содержит все нужные вещи.ПОМОГИТЕ!!!

= ОБНОВЛЕНИЕ =====================================================

Я использую% K и получаю странную ошибку времени выполнения:

if (searchResults1 != nil){
    NSLog(@"%Matches: %i", [searchResults1 count]);
}else {
    NSLog(@"Was NULL");
}

ВключеноNSLog (@ "% Matches: line. Это ошибка BAD EXC. Поэтому searchResults1 не равен nill, но вылетает, когда я пытаюсь прочитать счетчик?внутри него.

Ответы [ 3 ]

13 голосов
/ 17 марта 2011

Похоже, ваша проблема - ваш предикат:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(%@ contains[c] %@)", fieldKey,value];

Когда вы передадите fieldKey = @"fullname" и value = @"matt", этот предикат будет эквивалентен:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"('fullname' contains[c] 'matt')"];

Ты видишь проблему?Он рассматривает «полное имя» как необработанную строку, а не как имя поля.Это потому, что вы используете модификатор %@ в строке формата.Когда NSPredicate сталкивается с ними, он говорит: «Ага! Значение, которое здесь подставляется, будет константой».То, что вы действительно хотите сделать, это сказать «ага! Значение, которое здесь подставляется, будет идентификатором».

Поэтому вместо использования %@ используйте %K.Это специальный модификатор только для предикатов, и он означает замену в строке идентификатором (на самом деле как «путь к ключу»), что означает, что он сделает ваш предикат следующим образом:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(fullname contains[c] 'matt')"];

Вы ищете.

1 голос
/ 17 марта 2011

Я могу сказать по тому, как вы назвали свои переменные и параметры, что вы думаете в терминах SQL Базовые данные не являются SQL. Сущности не являются таблицами. Объекты не являются строками. Столбцы не являются атрибутами. Базовые данные - это система управления графом объектов, которая может сохранять или не сохранять объектный граф, а может и не использовать SQL для этого далеко за кулисами. Попытка представить базовые данные в терминах SQL приведет к тому, что вы полностью неправильно поймете базовые данные и приведет к большим трудностям и потерянному времени.

В этом блоке:

if (searchResults1 != nil){
    NSLog(@"%Matches: %i", [searchResults1 count]);
}else {
    NSLog(@"Was NULL");
}

... у тебя две проблемы здесь. Во-первых, searchResults1 никогда не будет нулевым. Независимо от того, найдет ли выборка какие-либо объекты, она вернет объект массива. Вместо этого вы должны проверить количество массивов. Во-вторых, %Matches это опечатка. % является управляющим символом форматирования и заставит компилятор искать управляющий код, например %@ сразу после. Попробуйте вместо этого:

if ([searchResults1 count]>0){
    NSLog(@"Matches: %i", [searchResults1 count]);
}else {
    NSLog(@"No managed objects found");
}
0 голосов
/ 28 марта 2011

Я забыл вернуть NSArray одним из моих вспомогательных методов.

...