NSPredicateEditorRowTemplate и CoreData
Я пытаюсь сгенерировать шаблоны редактора предикатов для моих сущностей Core Data. В моем коде у меня есть следующее:
NSEntityDescription *descrip = [NSEntityDescription entityForName:@"Person" inManagedObjectContext:managedObjectContext];
NSArray *templates = [NSPredicateEditorRowTemplate templatesWithAttributeKeyPaths:[NSArray arrayWithObjects:@"name", @"age", nil] inEntityDescription:descrip];
[ibPredicateEditor setRowTemplates: templates];
NSPredicate *p = [NSPredicate predicateWithFormat:@"name like 'John'"];
[ibPredicateEditor setObjectValue:p];
Распечатка содержимого массива шаблонов дает мне следующее:
CFArray 0x1002d7400 [0x7fff70ff5f20] {тип = неизменяемый, число = 2, значения = ( 0: NSPredicateEditorRowTemplate 0x10025c090: [имя] [99, 4, 5, 8, 9] NSStringAttributeType 1: NSPredicateEditor0dt 0 0100100c090: NSPtringAttributeType 1: 4 0, 2, 1, 3] NSInteger16AttributeType)}
Когда этот код выполняется, я получаю следующее на консоли:
Warning - unable to find template matching predicate name LIKE "John"
Интерфейс для этого выглядит предельно простым, поэтому я не могу понять, что я делаю неправильно. Любая помощь будет принята с благодарностью!
РЕДАКТИРОВАТЬ
Моя первоначальная проблема заключалась в том, что я использовал оператор LIKE, когда мои шаблоны не поддерживали его. Однако я не совсем понимаю, почему я получаю подобное предупреждение при передаче составного предиката в редактор.
NSPredicate *p = [NSPredicate predicateWithFormat:@"name CONTAINS 'John'"];
NSPredicate *p2 = [NSPredicate predicateWithFormat:@"name CONTAINS 'Jo'"];
NSPredicate *final = [NSCompoundPredicate andPredicateWithSubpredicates:[NSArray arrayWithObjects:p, p2, nil]];
[ibPredicateEditor setObjectValue: final];
ИЛИ ЖЕ
NSPredicate *final = [NSCompoundPredicate orPredicateWithSubpredicates:[NSArray arrayWithObjects:p, p2, nil]];
[ibPredicateEditor setObjectValue: final];
Оба из них производят подобные предупреждения как моя первоначальная проблема. Тем не менее, я нахожу странным, что я могу использовать один предикат и создавать составные компоненты и предикаты, но я не могу передать предварительно составленные составные компоненты и предикаты в редактор.
2 ответа
Шаблоны по умолчанию предоставляются NSPredicateEditorRowTemplate
за NSString
ключевые пути не поддерживают сравнения с оператором LIKE.
В сгенерированных вами шаблонах есть список операторов, которые он поддерживает:
NSPredicateEditorRowTemplate 0x10025c090: [name] [99, 4, 5, 8, 9] NSStringAttributeType
[99, 4, 5, 8, 9]
указывает на то, что имя NSString
Атрибут поддерживает:
4 - равно
5 - Не равно
8 - начинается с
9 - заканчивается с
99 - Содержит
(находится в NSComparisonPredicate.h)
CONTAINS похож на LIKE без подстановок% и _. Если вам требуется, вы всегда можете инициализировать свой собственный массив шаблонов.
Синтаксис немного многословен.
NSExpression *nameExpression = [NSExpression expressionForKeyPath:@"name"];
NSArray *operators = [NSArray arrayWithObjects:
[NSNumber numberWithInt: NSEqualToPredicateOperatorType],
[NSNumber numberWithInt:NSNotEqualToPredicateOperatorType],
[NSNumber numberWithInt:NSLikePredicateOperatorType],
[NSNumber numberWithInt:NSBeginsWithPredicateOperatorType],
[NSNumber numberWithInt:NSEndsWithPredicateOperatorType],
[NSNumber numberWithInt:NSContainsPredicateOperatorType],
nil];
NSUInteger options = (NSCaseInsensitivePredicateOption |
NSDiacriticInsensitivePredicateOption);
NSPredicateEditorRowTemplate *template = [[NSPredicateEditorRowTemplate alloc]
initWithLeftExpressions:[NSArray arrayWithObject:nameExpression]
rightExpressionAttributeType:NSStringAttributeType
modifier:NSDirectPredicateModifier
operators:operators
options:options];
Это может быть проблема с оператором LIKE. Этот код не регистрирует предупреждение:
NSPredicate *p;
p = [NSPredicate predicateWithFormat:@"name == 'John'"];
[ibPredicateEditor setObjectValue:p];
p = [NSPredicate predicateWithFormat:@"age > 18"];
[ibPredicateEditor setObjectValue:p];