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 receiveaParameter
as the parameter to the method-mySuperMethod:
will return aBOOL
that has been boxed in anNSNumber
<< 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. :)
精彩评论