Core Data NSPredicate удален == НЕТ не работает должным образом

Я использую UIManagedDocument с родительским дочерним контекстом.

В моем дочернем контексте я делаю следующее

Код 1

NSSet *results = [self.event.memberships filteredSetUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {

    return ([[evaluatedObject deleted] boolValue] == NO);

}]];

Приведенный выше код возвращает ожидаемые результаты (только не удаленные элементы для события).

Код 2

Но этого кода нет. Он извлекает все записи.

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"deleted == NO"];
NSSet *results = [self.event.memberships filteredSetUsingPredicate:predicate];

Это кажется запутанным. Оба должны возвращать одинаковые результаты, но predicateWithBlock возвращает правильные результаты, тогда как predicateWithFormat возвращает все записи.

Каковы плюсы и минусы использования predicateWithBlock вместо predicateWithFormat?


person krishnan    schedule 14.04.2013    source источник


Ответы (2)


Проблема в том, что вы определили атрибут deleted для своей сущности. Это конфликтует с методом isDeleted для NSManagedObject, поэтому вам следует переименовать этот атрибут.

Следующий «эксперимент» показывает, что странные вещи происходят, если вы называете свой атрибут «удаленным» (c — это управляемый объект с настраиваемым атрибутом deleted):

// Set custom "deleted" property to YES:
c.deleted = @YES;

// Use the property, as your Code 1
NSLog(@"%@", [c deleted]);
// Output: 1

// Use Key-Value Coding, as your Code 2
NSLog(@"%@", [c valueForKey:@"deleted"]);
// Output: 0

// Now really delete the object and try again:
[context deleteObject:c];
NSLog(@"%@", [c valueForKey:@"deleted"]);
// Output: 1

Ваш «Код 1» относится к свойству, поэтому он возвращает ожидаемый результат. «Код 2» использует кодирование «ключ-значение», а [c valueForKey:@"deleted"] возвращает YES, если объект действительно был удален из контекста!

Поэтому переименование этого атрибута должно решить вашу проблему. К сожалению, компилятор не выдает предупреждений, если имя атрибута конфликтует со встроенным методом.

person Martin R    schedule 14.04.2013
comment
Спасибо, это сработало. но isDeleted и delete - это два разных имени. когда я проверил заголовочный файл NSManagedObject.h // state - methods can be used through KVC, for example for enabling/disabling widgets based on the state of the object - (BOOL)isInserted; - (BOOL)isUpdated; - (BOOL)isDeleted;, возможно, Apple имеет какое-то частное свойство, например - person krishnan; 15.04.2013

Используйте заполнитель форматирования, чтобы заменить логическое значение:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%K == %@", @"deleted", @(NO)];

Ваше использование ключевого пути, вероятно, в порядке, но правая часть, вероятно, не выглядит как «НЕТ» для синтаксического анализатора.

person iluvcapra    schedule 14.04.2013
comment
[NSPredicate predicateWithFormat:@"%K == %@", @"deleted", @(NO)] то же, что и [NSPredicate predicateWithFormat:@"deleted == NO"], разницы нет. - person Martin R; 14.04.2013