The docs for NSArray give these three functions using blocks:
enumerateObjectsUsingBlock:
enumerateObjectsWithOptions:usingBlock:
enumerateObjectsAtIndexes:options:usingBlock:
As the reference indicates, these methods require a particular form of block with this signature:
^(id s, NSUInteger i, BOOL *stop)
(Apple uses
idx
for i
). The stop
flag is meant to tbe used to bail from an iteration when the first matching object is found. The index is not a loop counter but shows the index of the current object within the array.// clang blocks2.m -o prog -framework Foundation -fobjc-gc-only #import <Foundation/Foundation.h> typedef void (^B) (id s, NSUInteger idx, BOOL *stop); int main(int argc, char * argv[]){ B b = ^(id s, NSUInteger i, BOOL *stop) { NSLog(@"i = %lu, pre : s = %@", i, s); if ([s caseInsensitiveCompare:@"B"] == 0) { NSLog(@"setting stop, s = %@", s); *stop = YES; } NSLog(@"post: s = %@", s); }; NSArray *arr = [NSArray arrayWithObjects:@"a",@"B",@"c",@"d",nil]; [arr enumerateObjectsUsingBlock:b]; printf("------------------------------\n"); //NSUint o = NSEnumerationReverse; uint o = NSEnumerationReverse; [arr enumerateObjectsWithOptions:o usingBlock:b]; printf("------------------------------\n"); NSIndexSet *is; NSRange R = NSMakeRange(2,2); is = [NSIndexSet indexSetWithIndexesInRange:R]; [arr enumerateObjectsAtIndexes:is options:NO usingBlock:b]; return 0; } |
> ./prog 2012-05-18 09:02:07.791 prog[382:707] i = 0, pre : s = a 2012-05-18 09:02:07.793 prog[382:707] post: s = a 2012-05-18 09:02:07.794 prog[382:707] i = 1, pre : s = B 2012-05-18 09:02:07.795 prog[382:707] setting stop, s = B 2012-05-18 09:02:07.795 prog[382:707] post: s = B ------------------------------ 2012-05-18 09:02:07.796 prog[382:707] i = 3, pre : s = d 2012-05-18 09:02:07.796 prog[382:707] post: s = d 2012-05-18 09:02:07.797 prog[382:707] i = 2, pre : s = c 2012-05-18 09:02:07.797 prog[382:707] post: s = c 2012-05-18 09:02:07.798 prog[382:707] i = 1, pre : s = B 2012-05-18 09:02:07.798 prog[382:707] setting stop, s = B 2012-05-18 09:02:07.799 prog[382:707] post: s = B ------------------------------ 2012-05-18 09:02:07.799 prog[382:707] i = 2, pre : s = c 2012-05-18 09:02:07.800 prog[382:707] post: s = c 2012-05-18 09:02:07.800 prog[382:707] i = 3, pre : s = d 2012-05-18 09:02:07.801 prog[382:707] post: s = d |
Another NSArray method that uses a block is
sortedArrayUsingComparator
. Here's an example adapted from the Apple docs, followed by a slightly modified approach.// clang blocks3.m -o prog -framework Foundation -fobjc-gc-only #import <Foundation/Foundation.h> void show(NSArray *a) { for (id obj in a) { NSLog(@"%@", [obj description]); } } int main(int argc, char * argv[]) { NSArray *a; a = [NSArray arrayWithObjects:@"1",@"21",@"12",@"11",@"02",nil]; NSStringCompareOptions o1, o2, o3, o4; o1 = NSCaseInsensitiveSearch; o2 = NSNumericSearch; o3 = NSWidthInsensitiveSearch; o4 = NSForcedOrderingSearch; NSStringCompareOptions o = o2; NSLocale *loc = [NSLocale currentLocale]; NSComparator cmp = ^(id s1, id s2) { NSRange R = NSMakeRange(0, [s1 length]); return [s1 compare:s2 options:o range:R locale:loc]; }; NSArray *result = [a sortedArrayUsingComparator:cmp]; show(result); NSComparator cmp2 = ^(id s1, id s2) { NSNumber *x = [NSNumber numberWithInt:[s1 intValue]]; NSNumber *y = [NSNumber numberWithInt:[s2 intValue]]; return (NSComparisonResult)[x compare:y]; }; result = [a sortedArrayUsingComparator:cmp2]; show(result); return 0; } |
Both versions give the same output:
2012-05-18 13:31:41.071 prog[902:707] 1 2012-05-18 13:31:41.073 prog[902:707] 02 2012-05-18 13:31:41.074 prog[902:707] 11 2012-05-18 13:31:41.074 prog[902:707] 12 2012-05-18 13:31:41.075 prog[902:707] 21 |
One more NSArray method that uses a block is
indexesOfObjectsPassingTest
. This example is also adapted from the Apple docs. It's followed by use of a block and enumerateIndexesUsingBlock
to enumerate the resulting NSIndexSet.// clang blocks5.m -o prog -framework Foundation -fobjc-gc-only #import <Foundation/Foundation.h> int main(int argc, char * argv[]) { NSString *s = [NSString stringWithFormat:@"A B C A B Z G Q"]; NSArray *a = [s componentsSeparatedByString:@" "]; NSSet *filterSet = [NSSet setWithObjects:@"A", @"C", @"Q", nil]; BOOL (^test) (id obj, NSUInteger idx, BOOL *stop); test = ^ (id obj, NSUInteger idx, BOOL *stop) { if (idx < 5) { if ([filterSet containsObject:obj]) { return YES; } } return NO; }; NSIndexSet *iset = [a indexesOfObjectsPassingTest:test]; [iset enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL *stop) { NSLog(@"%lu", idx); } ]; return 0; } |
> ./prog 2012-05-18 17:03:26.348 prog[1477:707] 0 2012-05-18 17:03:26.351 prog[1477:707] 2 2012-05-18 17:03:26.351 prog[1477:707] 3 |