blocks 学习

来源:互联网 发布:知乎 璇玑图 编辑:程序博客网 时间:2024/06/04 23:30


http://www.cnblogs.com/scorpiozj/archive/2011/01/21/1941008.html

Ios4已经直接支持blocks,很有必要学习一下。

在ios,blocks是对象,它封装了一段代码,这段代码可以在任何时候执行。Blocks可以作为函数参数或者函数的返回值,而其本身又可以带输入参数或返回值。它和传统的函数指针很类似,但是有区别:blocks是inline的,并且它对局部变量是只读的。

Blocks的定义:

         int (^Multiply)(int,int) = ^(int num1,int num2) {return num1 * num2;};

定义了一个Multiply的blocks对象,它带有两个int参数,返回int。等式右边就是blocks的具体实现,注意{}blocks体里的;。

Blocks可以访问局部变量,但是不能修改。

              int multiplier = 7;

     int (^myBlock)(int) = ^(int num) {

         multiplier ++;//编译报错

         return num * multiplier;

     };

如果要修改就要加关键字:__block

         __blockint multiplier =7;

     int (^myBlock)(int) = ^(int num) {

         multiplier ++;//这样就可以了

         return num * multiplier;

     };

 

作为函数的参数,blocks某种意义上替代了回调函数或者delegate。当函数调用了,假设某个事件触发,这时blocks里的内容就会运行。这样有利于代码的整合和阅读,你不需要到处去实现委托方法了。

系统API中已经有很多支持blocks参数了

·       Completionhandlers

·       Notificationhandlers

·       Errorhandlers

·       Enumeration

·       Viewanimation 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:^(id obj,NSUInteger idx,BOOL *stop) {

                                                                NSString  *tmpStr = (NSString *)obj;

                                                                return [tmpStrhasPrefix:area];

                                                            }];

   

    NSArray *tmpArray = [timeZoneNamesobjectsAtIndexes:areaIndexes];

    [tmpArray enumerateObjectsWithOptions:NSEnumerationConcurrent|NSEnumerationReverse

                               usingBlock:^(id obj,NSUInteger idx,BOOL *stop) {

                                   [areaArrayaddObject:[obj substringFromIndex:[arealength]+1]];

                               }];

    NSLog(@"Cities in %@ timezone:%@", area, areaArray);

blocks中obj就是数组中的每个成员,我们就可以在blocks内对每个对象进行处理。再比如:

NSMutableArray *mArray = [NSMutableArrayarrayWithObjects:@"a",@"b",@"abc",nil];

    NSMutableArray *mArrayCount= [NSMutableArrayarrayWithCapacity:1];

    [mArray enumerateObjectsWithOptions:NSEnumerationConcurrentusingBlock: ^(id obj,NSUInteger idx,BOOL *stop){

        [mArrayCount addObject:[NSNumbernumberWithInt:[objlength]]];

    }];

   

    NSLog(@"%@",mArrayCount);

你会发现,这样写代码更容易读懂。

最后,看一个排序的例子:

    NSArray *stringsArray = [NSArrayarrayWithObjects:

                             @"string1",

                             @"String21",

                             @"string12",

                             @"String11",

                             @"String02",nil];

    staticNSStringCompareOptionscomparisonOptions =NSCaseInsensitiveSearch |NSNumericSearch |

    NSWidthInsensitiveSearch|NSForcedOrderingSearch;

    NSLocale *currentLocale = [NSLocalecurrentLocale];

    NSComparator finderSort =^(idstring1,id string2) {

        NSRange string1Range =NSMakeRange(0, [string1length]);

        return [string1compare:string2options:comparisonOptionsrange:string1Rangelocale:currentLocale];

    };

    NSLog(@"finderSort: %@",[stringsArraysortedArrayUsingComparator:finderSort]);

结果:finderSort:(

    "string 1",

    "String 02",

    "String 11",

    "string 12",

    "String 21"

)