Использование SELF NSP-предиката вне строки формата - PullRequest
1 голос
/ 09 июня 2011

Я использую fetchedResultsController в хранилище CoreData и хочу создать предикат, который даст мне fetchedObjects в соответствии с этой концепцией:

[NSPredicate predicateWithFormat:@"%i > 0", [self countForObject:SELF]]

countForObject - это метод, который возвращает целое число на основе параметраanObject, который я хочу быть собой.

EDIT

Кажется, я должен использовать блоки для этого.Я склеил некоторый код вместе, но мое приложение вылетает без обратной связи при его использовании:

    [NSPredicate predicateWithBlock:^BOOL(id object, NSDictionary *bindings){
        return ([self countForObject:object] > 0);
    }];

1 Ответ

4 голосов
/ 09 июня 2011

Ваша проблема в том, что вы используете self и используете неспецифический тест.

Похоже, вы хотите, чтобы он ссылался на управляемые объекты, которые тестирует предикат, но он фактически ссылается на объект времени выполнения, в котором появляется код (предположительно, контроллер табличного представления). Использование блока не решает проблему из-за«перетаскивание области», при котором блоки работают в той же области, из которой они вызваны.

Итак, ваш код на самом деле работает так:

[NSPredicate predicateWithFormat:@"%i > 0", [myTableViewController countForObject:aPresumedConstant]];

... и код блока имеет ту же проблему.

Ваш тест неспецифичен, поскольку вы не проверяете атрибут управляемых объектов.Вместо этого вы создаете тест, который имеет значение true или false для всех управляемых объектов объекта извлечения.

Даже если ваша ссылка self вернула полезное значение, она вернет только одно значение.Предположим, ваш countForObject: возвращает -1,0,1 каждый в отдельном прогоне.Во время выполнения ваш предикат будет разрешать что-то вроде этого:

[NSPredicate predicateWithFormat:@"false", -1]; // -1<0 so %i>0 always resolves to false
[NSPredicate predicateWithFormat:@"false", 0]; // 0==0 so %i>0 always resolves to false
[NSPredicate predicateWithFormat:@"true", -1]; // 1>0 so %i>0 always resolves to true

В первых двух случаях выборка будет возвращать ноль объектов, тогда как последний возвращает все объекты объекта выборки.

Вы, вероятно, видели, как self используется в предикатах, что-то вроде этого:

[NSPredicate predicateWithFormat:@"SELF == %@", anObject];

Разница в том, что SELF встречается в кавычках и, следовательно, становится частьюсообщение, которое предикат отправляет тестируемым объектам.По сути, предикат говорит: «Вы соответствуете ли SELF-ключ SELF-ключу anObject?»Поскольку каждый объект понимает свое собственное значение SELF, каждый объект может возвращать отдельное значение true или false в ответ.

Если вы хотите, чтобы каждый управляемый объект отвечал на тестирование на countForObject, вам нужно сделать countForObject и атрибут / свойство объекта / класса для управляемого объекта.Обычно вы создаете временное свойство, которое будет вычислять значение при каждом запросе, но не сохранит его в хранилище.

Вы бы использовали что-то вроде этого:

[NSPredicate predicateWithFormat:@"SELF == %@", anObject];
...