NSFetchRequest и attributeateWithBlock

Я играю с приложением, которое использует Core Data и NSManagedObjects для заполнения UITableView. В моем приложении есть только один класс, который называется Event . Я создал следующий пользовательский метод экземпляра для события Event :

- (BOOL)isExpired {
    return ([[self.endOn dateAtEndOfDay] timeIntervalSinceNow] < 0);
}

Я хотел бы ограничить UITableView , который отображает объекты Event , только событиями с истекшим сроком действия, то есть где isExpired возвращает ДА . Я попытался сделать это, добавив NSPredicate к NSFetchRequest :

NSPredicate *predicate = [NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary * bindings) {return([evaluatedObject isExpired]);}];
[fetchRequest setPredicate:predicate];

, но получаю ошибку: *** Завершение работы приложения из-за необработанного исключения «NSInvalidArgumentException» Причина: 'Проблема с субпредикатом BLOCKPREDICATE (0x272ac)' *** . Означает ли это, что вы не можете использовать блочный предикат с NSFetchRequest? Или я просто неправильно его сконструировал?

Спасибо!

26
задан Bill Smithed 22 August 2010 в 20:22
поделиться

1 ответ

Итак, похоже, что мы установили в комментариях к исходному сообщению, что это, вероятно, вызвано несовместимостью хранилищ SQLite с предикатами блоков, поскольку Core Data не может преобразовать их в SQL для запуска их в магазине (спасибо, JoostK).

Есть несколько способов преодолеть это:

  • При условии, что конечная дата ваших объектов является обычным атрибутом, вы могли бы выразить ограничение срока действия как строку формата предиката вместо предиката блока, какие Core Data можно преобразовать в предложение SQL.
  • Если это возможно, вы, вероятно, предпочтете использовать шаблон запроса на выборку для получения просроченных элементов. Однако вам нужно будет передать переменную подстановки, например $ NOW , чтобы получить доступ к текущей дате. Это дает то преимущество, что шаблон предиката отображается в редакторе модели.
  • Оба подхода, однако, имеют недостаток, заключающийся в дублировании существующих функций (например, ваш метод isExpired ). Таким образом, другим способом было бы сначала получить все квалифицируемые сущности независимо от их состояния истечения срока действия, а затем запустить специальный этап фильтрации для результирующего набора сущностей, чтобы отсеять те, которые не истекли. Поскольку к этому моменту они были полностью воскрешены из магазина, вы должны иметь возможность использовать для этого предикат блока.
24
ответ дан 28 November 2019 в 07:49
поделиться
Другие вопросы по тегам:

Похожие вопросы: