iOS - NSPredicate string.length всегда оценивается как 0, когда строка начинается с арифметических операторов + - * /

У меня есть простой метод, который использует NSPredicate для возврата количества строк, где comment.length > 0.

Проблема в том, что я обнаружил, что когда столбец комментариев начинается с + - * или /, свойство длины всегда оценивается как 0, и поэтому строка исключается из подсчета.

Я открыл таблицу в браузере SQLite и проверил, что столбец является VARCHAR. Использование запроса SQLite для проверки длины строки работает нормально (LENGTH(ZComments) > 0), так что это должно быть проблемой CoreData.

Вот моя функция...

-(int)getCommentsCount{
    NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease];
    [request setIncludesSubentities:YES];
    [request setEntity:[NSEntityDescription entityForName:@"InspectionRecord" inManagedObjectContext:managedObjectContext]];

    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(comments.length > 0)"];
    [request setPredicate:predicate];

    NSError *err;
    NSUInteger count = [managedObjectContext countForFetchRequest:request error:&err];

    //count is ALWAYS 0 if 'comments' starts with + - * or /     WHYYY???      
    return count;
}

Я смог обойти это, проверив пустую/нулевую строку вместо использования .length, но мне очень хотелось бы знать, почему .length терпит неудачу, когда строка начинается с определенных символов.

Это случилось с кем-нибудь?


person iupchris10    schedule 31.03.2014    source источник
comment
Не причина вашей ошибки, но сигнатура метода должна быть -(NSUInteger)commentsCount. Сопоставьте тип возвращаемого значения -countForFetchRequest:error: и не начинайте имена методов с get, если только они косвенно не возвращают несколько элементов (Соглашения об именах какао).   -  person Hal Mueller    schedule 31.03.2014


Ответы (1)


Вы не можете использовать функции Objective-C, такие как length, в запросе на выборку Core Data (и часть «.length» просто игнорируется, когда Core Data переводит запрос на выборку в запрос SQLite). Но вместо этого вы можете просто сравнить с пустой строкой:

 [NSPredicate predicateWithFormat:@"comment != ''"]

Для других запросов, связанных с длиной, вы можете использовать оператор MATCHES с регулярным выражением, как показано здесь: CoreData предикат: длина строкового свойства?.

person Martin R    schedule 31.03.2014
comment
Кроме того, иногда может показаться, что использование .length работает по той причине, что Core Data преобразует comments.length > 0 в SQL как что-то вроде t0.ZCOMMENTS > 0, теряя часть длины запроса. Это кажется мне ошибкой, но на данный момент это так. Я не знаю, как SQLite оценивает строки при сравнении > 0, но это не то, что подразумевается под comments.length. - person Tom Harrington; 31.03.2014
comment
Отличное объяснение, спасибо! Я даже проверил это, изменив .length на .foo и получил те же результаты. Есть ли законный способ сравнить длину строки с помощью NSPredicate? Кроме того.... кому-то лучше сказать людям в этом другом потоке, что они делают что-то неправильно.... stackoverflow.com/questions/7369390/ - person iupchris10; 31.03.2014
comment
@iupchris10: comment.length › 0 и подобное работает, когда, например. фильтрующие массивы. Это не удается только для запросов на выборку основных данных (и это уже упоминалось в одном комментарии к ответу). - person Martin R; 31.03.2014
comment
@ iupchris10: Другие сравнения длин строк можно выполнять с помощью регулярных выражений (как в ответе, на который я ссылался). - person Martin R; 31.03.2014
comment
@MartinR - спасибо. Я также только что наткнулся на этот поток, в котором предлагается добавить свойство длины к вашему управляемому объекту и установить его всякий раз, когда изменяется текстовое значение. - [ссылка]stackoverflow.com /вопросы/3644621/ - person iupchris10; 31.03.2014