欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

IOS开发(47)之iOS Block学习

程序员文章站 2022-06-07 15:00:54
ios4已经直接支持blocks,很有必要学习一下。 在ios,blocks是对象,它封装了一段代码,这段代码可以在任何时候执行。blocks可以作为函数参数或者函数的返回值,而...

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"

)