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 |