现在的位置: 首页 > 综合 > 正文

iOS Block学习

2013年09月18日 ⁄ 综合 ⁄ 共 3334字 ⁄ 字号 评论关闭

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"

)

关于blocks更详细的信息可参见:http://bukkake.iteye.com/blog/1168602

抱歉!评论已关闭.