开发者

How can I perform an NSArray filteredArrayUsingPredicate where the predicate is a method?

How can I perform an NSArray filteredArrayUsingPredicate where the predicate is a method? That is what would a simple code example look like here?

I've been trying to go through the predicate doco and getting a little confused. I can see how it w开发者_开发技巧orks for simple checks, but if I have a check which requires a few lines of objective-c code to implement what would the code look like to effectively:

  • filter an NSArray using filteredArrayUsingPredicate
  • predicate would be a method which somehow takes an input variable(s), performs whatever checks and balances and then gives a TRUE/FALSE back as a return value re whether the item should be filtered or not

thanks


As long as you're going with iOS 4.0 and above you'll be glad to know this is really straightforward (the following isn't available on 3.x).

You can use the predicateWithBlock method to create a NSPredicate that takes a block that returns YES or NO as its argument. So pretty much exactly what you want (if you're not familiar with blocks they're basically a way to encapsulate a method. See here: http://pragmaticstudio.com/blog/2010/7/28/ios4-blocks-1)

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


You can use the predicateWithBlock: approach that @lxt suggested, or you can use the FUNCTION approach. This would have you build a predicate that looks like this:

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

If you use that predicate to filter an array, then:

  • SELF will iteratively be each item in the array
  • each item in the array will have its -mySuperMethod: method invoked
  • -mySuperMethod: will receive aParameter as the parameter to the method
  • -mySuperMethod: will return a BOOL that has been boxed in an NSNumber << this is very important
  • all of the objects that return YES from -mySuperMethod: will be included in the filtered array.

For more information on this syntax, check out this blog post.

So why might you want to use this approach over the block approach? I can think of two reasons:

  • Backwards Compatibility
    • If you need this to work on Leopard (blocks on the Mac were introduced in Snow Leopard).
    • If you need this to work on iOS pre-4.0 (blocks on iOS were introduced in iOS 4.0).
  • You want to serialize the predicate for archival and later retrieval. This is fine as long as aParameter conforms to the <NSCoding> protocol. Blocks cannot be serialized.

However, if neither of those are requirements, then the block approach will probably be better in the long run, since it's more obvious and readable. :)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜