IOS开发(47)之iOS Block学习
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可以访问局部变量,但是不能修改。比如下面的代码就会报编译错
int num = 0;
//使用block
int (^myblock) (int a,int b) = ^(int a,int b){
num = a+b;
return num;
};
如果要修改就要加关键字:__block (注意,是两个下划线"_")
__block int num = 0;
//使用block
int (^myblock) (int a,int b) = ^(int a,int b){
num = a+b;
return num;
};
作为函数的参数,blocks某种意义上替代了回调函数或者delegate。当函数调用了,假设某个事件触发,这时blocks里的内容就会运行。这样有利于代码的整合和,你不需要到处去实现委托方法了。
api中已经有很多支持blocks参数了
· completion handlers
· notification handlers
· error handlers
· enumeration
· view animation and transitions
· sorting
例如:
[uiview animatewithduration:(nstimeinterval)duration animations:(void (^)())animations]
集合体中也可以运用blocks。枚举一个数组时我们通常:
for (id obj in array);
现在,
nsstring *area = @"europe";
nsarray *timezonenames = [nstimezone knowntimezonenames];
nsmutablearray *areaarray = [nsmutablearray arraywithcapacity:1];
nsindexset *areaindexes = [timezonenames indexesofobjectswithoptions:nsenumerationconcurrent
passingtest:^(id obj, nsuinteger idx, bool *stop) {
nsstring *tmpstr = (nsstring *)obj;
return [tmpstr hasprefix:area];
}];
nsarray *tmparray = [timezonenames objectsatindexes:areaindexes];
[tmparray enumerateobjectswithoptions:nsenumerationconcurrent|nsenumerationreverse
usingblock:^(id obj, nsuinteger idx, bool *stop) {
[areaarray addobject:[obj substringfromindex:[area length]+1]];
}];
nslog(@"cities in %@ time zone:%@", area, areaarray);
在blocks中obj就是数组中的每个成员,我们就可以在blocks内对每个对象进行处理。再比如:
nsmutablearray *marray = [nsmutablearray arraywithobjects:@"a",@"b",@"abc",nil];
nsmutablearray *marraycount = [nsmutablearray arraywithcapacity:1];
[marray enumerateobjectswithoptions:nsenumerationconcurrent usingblock: ^(id obj,nsuinteger idx, bool *stop){
[marraycount addobject:[nsnumber numberwithint:[obj length]]];
}];
nslog(@"%@",marraycount);
你会发现,这样写代码更容易读懂。
最后,看一个排序的例子:
nsarray *stringsarray = [nsarray arraywithobjects:
@"string 1",
@"string 21",
@"string 12",
@"string 11",
@"string 02", nil];
static nsstringcompareoptions comparisonoptions = nscaseinsensitivesearch | nsnumericsearch |
nswidthinsensitivesearch | nsforcedorderingsearch;
nslocale *currentlocale = [nslocale currentlocale];
nscomparator findersort = ^(id string1, id string2) {
nsrange string1range = nsmakerange(0, [string1 length]);
return [string1 compare:string2 options:comparisonoptions range:string1range locale:currentlocale];
};
nslog(@"findersort: %@", [stringsarray sortedarrayusingcomparator:findersort]);
结果:findersort: (
"string 1",
"string 02",
"string 11",
"string 12",
"string 21"
)