iOS4已经直接支持blocks,很有必要学习一下。
在ios,blocks是对象,它封装了一段代码,这段代码可以在任何时候执行。Blocks可以作为函数参数或者函数的返回值,而其本身又可以带输入参数或返回值。它和传统的函数指针很类似,但是有区别:blocks是inline的,并且它对局部变量是只读的。
Blocks的定义:
int (^myBlock) (int a,int b) = ^(int a,int b){ return a+b; };
定义了一个名为myBlock的blocks对象,它带有两个int参数,返回int。等式右边就是blocks的具体实现,是不是有点像方法的定义?
Blocks可以访问局部变量,但是不能修改。比如下面的代码就回报编译错
如果要修改就要加关键字:__block (注意,是两个下划线"_")
作为函数的参数,blocks某种意义上替代了回调函数或者delegate。当函数调用了,假设某个事件触发,这时blocks里的内容就会运行。这样有利于代码的整合和阅读,你不需要到处去实现委托方法了。
系统API中已经有很多支持blocks参数了
·Completion handlers
·Notification handlers
·Error handlers
·Enumeration
·View animation and transitions
·Sorting
例如:
[UIViewanimateWithDuration:(NSTimeInterval)durationanimations:(void (^)())animations]
集合体中也可以运用blocks。枚举一个数组时我们通常:
for (id obj in Array);
现在,
NSString*area =@"Europe";
NSArray*timeZoneNames = [NSTimeZoneknownTimeZoneNames];
NSMutableArray*areaArray = [NSMutableArrayarrayWithCapacity:1];
NSIndexSet*areaIndexes = [timeZoneNamesindexesOfObjectsWithOptions:NSEnumerationConcurrent
passingTest:^(idobj,NSUIntegeridx,BOOL*stop) {
NSString*tmpStr = (NSString*)obj;
return[tmpStrhasPrefix:area];
}];
NSArray*tmpArray = [timeZoneNamesobjectsAtIndexes:areaIndexes];
[tmpArrayenumerateObjectsWithOptions:NSEnumerationConcurrent|NSEnumerationReverse
usingBlock:^(idobj,NSUIntegeridx,BOOL*stop) {
[areaArrayaddObject:[objsubstringFromIndex:[arealength]+1]];
}];
NSLog(@"Cities in %@ time zone:%@", area, areaArray);
在blocks中obj就是数组中的每个成员,我们就可以在blocks内对每个对象进行处理。再比如:
NSMutableArray*mArray = [NSMutableArrayarrayWithObjects:@"a",@"b",@"abc",nil];
NSMutableArray*mArrayCount = [NSMutableArrayarrayWithCapacity:1];
[mArrayenumerateObjectsWithOptions:NSEnumerationConcurrentusingBlock: ^(idobj,NSUIntegeridx,BOOL*stop){
[mArrayCountaddObject:[NSNumbernumberWithInt:[objlength]]];
}];
NSLog(@"%@",mArrayCount);
你会发现,这样写代码更容易读懂。
最后,看一个排序的例子:
NSArray*stringsArray = [NSArrayarrayWithObjects:
@"string 1",
@"String 21",
@"string 12",
@"String 11",
@"String 02",nil];
staticNSStringCompareOptionscomparisonOptions =NSCaseInsensitiveSearch|NSNumericSearch|
NSWidthInsensitiveSearch|NSForcedOrderingSearch;
NSLocale*currentLocale = [NSLocalecurrentLocale];
NSComparatorfinderSort = ^(idstring1,idstring2) {
NSRangestring1Range =NSMakeRange(0, [string1length]);
return[string1compare:string2options:comparisonOptionsrange:string1Rangelocale:currentLocale];
};
NSLog(@"finderSort: %@", [stringsArraysortedArrayUsingComparator:finderSort]);
结果:finderSort: (
"string 1",
"String 02",
"String 11",
"string 12",
"String 21"
)