Как я могу выполнить NSArray FilterArrayUsingPredicate, где предикат является методом? - PullRequest
4 голосов
/ 20 марта 2011

Как я могу выполнить NSArray FilterArrayUsingPredicate, где предикат является методом?Вот как будет выглядеть простой пример кода здесь:

Я пытался пройтись по предикатному доку и немного запутался.Я могу видеть, как это работает для простых проверок, но если у меня есть проверка, которая требует нескольких строк кода Objective-C для реализации того, как код будет выглядеть эффективно:

  • фильтрует NSArray, используяПредикат FilterArrayUsingPredicate
  • - это метод, который каким-то образом принимает входную переменную (и), выполняет любые проверки и балансировки, а затем возвращает значение ИСТИНА / ЛОЖЬ в качестве возвращаемого значения, независимо от того, должен ли элемент фильтроваться или нет

спасибо

Ответы [ 2 ]

7 голосов
/ 20 марта 2011

Пока вы работаете с iOS 4.0 и выше, вы будете рады узнать, что это действительно просто (следующее не доступно в 3.x).

Вы можете использовать метод predicateWithBlock, чтобы создать NSPredicate, который принимает блок, который возвращает YES или NO в качестве аргумента. В общем, именно то, что вы хотите (если вы не знакомы с блоками, это просто способ инкапсулировать метод. См. Здесь: http://pragmaticstudio.com/blog/2010/7/28/ios4-blocks-1)

+ (NSPredicate *)predicateWithBlock:(BOOL (^)(id evaluatedObject, NSDictionary *bindings))block

6 голосов
/ 20 марта 2011

Вы можете использовать predicateWithBlock: подход, который предложил @lxt, или вы можете использовать FUNCTION подход. Это позволит вам создать предикат, который выглядит следующим образом:

[NSPredicate predicateWithFormat:@"FUNCTION(SELF, 'mySuperMethod:', %@)", aParameter];

Если вы используете этот предикат для фильтрации массива, то:

  • SELF итеративно будет каждым элементом в массиве
  • для каждого элемента в массиве будет вызываться -mySuperMethod: метод
  • -mySuperMethod: получит aParameter в качестве параметра для метода
  • -mySuperMethod: вернет BOOL , который был упакован в NSNumber <<, это очень важно </li>
  • все объекты, которые возвращают YES из -mySuperMethod:, будут включены в отфильтрованный массив.

Для получения дополнительной информации об этом синтаксисе, прочитайте это сообщение в блоге .

Так почему вы можете использовать этот подход вместо блочного? Я могу думать о двух причинах:

  • Обратная совместимость
    • Если вам это нужно для работы на Leopard (блоки для Mac были введены в Snow Leopard).
    • Если вам это нужно для работы на iOS до 4.0 (блоки для iOS были введены в iOS 4.0).
  • Вы хотите сериализовать предикат для архивирования и последующего извлечения. Это нормально, если aParameter соответствует протоколу <NSCoding>. Блоки не могут быть сериализованы.

Однако, если ни одно из этих требований не является обязательным, блочный подход, вероятно, будет лучше в долгосрочной перспективе, поскольку он более очевиден и удобочитаем. :)

...