iOS Core Data, как правильно сравнивать текст строки, используя предикаты? - PullRequest
6 голосов
/ 22 марта 2012

Это буквально сводит меня с ума.

У меня есть 2 объекта, которые используют NSStrings в качестве уникального атрибута.

Как правильно создать предикат, сравнивающий строки NSStrings?

В настоящее время у меня есть: [NSPredicate ultimateateWithFormat.У меня такое ощущение, что это сравнивает адреса указателей, а не фактические строковые значения, но я не могу это подтвердить.Мне нужно вернуть да для точного совпадения строк.

-(BOOL)uniqueEntityExistsWithEnityName:(NSString*)entityName UniqueKey:(NSString*) uniqueKey UniqueValue:(NSString*)uniqueValue SortAttribute:(NSString*)sortDescriptorAttribute ManagedObjectContext:(NSManagedObjectContext*) context;
{
    BOOL returnValue = NO;

    NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:entityName];

//what is the correct predates to compare the text an string core data property against a passed in string?
    request.predicate = [NSPredicate predicateWithFormat:@"unique= %@", uniqueValue];

    NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:sortDescriptorAttribute ascending:YES];
    request.sortDescriptors = [NSArray arrayWithObject:sortDescriptor];   

    NSError *error = nil;
    NSArray *matches = [context executeFetchRequest:request error:&error];
    if (!matches)
    {
         NSLog(@"Error: no object matches");
    }
    else if([matches count] > 1) {
        NSLog(@"Error: More than one object for unique record");
        returnValue = YES;

    } else if ([matches count] == 0) {
        returnValue = NO;
    } else {
        returnValue = YES;
    }

    return returnValue;
}

Ответы [ 2 ]

9 голосов
/ 22 марта 2012

Один знак равенства даже не является компаратором с точки зрения кодирования.

Я собираюсь предположить, что уникальным является атрибут NSManagedObject.

[NSPredicate predicateWithFormat:@"unique LIKE %@", uniqueValue];

Обратите внимание, что это регистрчувствительны.Если вы хотите сделать его нечувствительным, вы можете поставить [c] после LIKE.

7 голосов
/ 23 марта 2012

Я не вижу проблемы с вашим предикатом. Один = идеально подходит, если вы хотите соответствовать точным строкам. Если вам не нужно сопоставление с подстановочными знаками, вам не нужно медленное LIKE. ( Синтаксис строки формата предиката )

Однако в вашем коде есть проблема, и она может привести вас к неверным предположениям. Ваше if / then / else или хотя бы первое сообщение является своего рода неправильным. Если выборка не возвращает массив, это означает, что выборка не удалась, это не означает, что выборка не возвращала объекты.

Это должно быть больше так:

if (!matches)
{
    NSLog(@"Error: couldn't execute fetch request %@", error);
}
else if([matches count] > 1) {
    NSLog(@"Error: More than one object for unique record");
    returnValue = YES;
} else if ([matches count] == 0) {
    NSLog(@"couldn't match objects");
    returnValue = NO;
} else {
    // [matches count] == 1
    NSLog(@"matched one object");
    returnValue = YES;
}

О, и я бы изменил порядок условий. По моему мнению, структура типа (! Совпадений), ([количество совпадений] == 1), ([количество совпадений] == 0), (еще) имеет больше смысла, и ее легче читать. Вы ставите самое важное (потому что это то, что вы действительно хотите) условие в последнем «анонимном» остальном.

...