微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何在iOS中使用Block

Block可以帮助我们组织独立的代码段,并提高复用性和可读性。iOS4在UIKit中引入了该特征。超过100个的Apple API都使用了Block,所以这是一个我们必须开始熟悉的知识。


Block是什么样的? 
你可以使用^操作符来声明一个Block变量,它表示一个Block的开始。

 
 
  1. int num1 = 7;  
  2. int(^aBlock)(int) = ^(int num2) {  
  3.    return num1+nunm2;  
  4. };  

在如上代码中我们将Block声明为一个变量,所以可以将它当做一个函数中使用:

  • NSLog(@"%d", aBlock(49)); //adds 49 to 7 which gives us 56.  
  • 我们刚看过了将block当做变量的情况,但通常情况下我们会以内联的方式使用Block,比如在一个变量中。API要么会使用Block在一个对象集合上执行某种操作,要么将其作为一个操作完成后的回调。

  • NSComperator compareStringsBlock = ^(id stringA, id stringB) {  
  • NSRange rangeS  = NSMakeRange (0, [stringA length]);  
  •   return (stringA compare:stringB options:comparisonoptions range:rangeS locale:currentLocale];  
  • };  
  •  
  • NSArray *compareSortArray  = [arrayofstringDays sortArrayUsingComparator: compareStringsBlock]);  
  • Block具有将临时函数体创建为表达式的优势。Apple文档中指出: 
    Block是符合如下要求的匿名内联的代码集:

    • 函数一样具有一个指定类型的参数列表
    •  有一个可以推导或声明的返回值类型
    • 可以从它被定义的词义范围中捕捉状态
    • 可以在需要的时候改变词义范围的状态
    • 可以和相同的词义范围中定义的其他的Block共享更改的可能。
    • 可以在词义范围(堆栈帧)被销毁后继续共享和修改该词义范围(堆栈帧)的状态。

    Block是一个自包含的小代码段,封装了用于遍历(线性遍历)或者回调,可以并发执行的任务单元。


    声明和使用Block 
    Apple文档中介绍了如何将一个Block声明为变量,并将其作为一个函数使用:
     

     
     
    1. int (^oneFrom)(int) = ^(int anInt) {  
    2.     return anInt - 1;  
    3. };  
    4. // 我们创建了一个内联块^(int anInt)... ,其函数体和结果被传到了另外一个名为OneFrom的Block。  
    5.  
    6. printf("1 from 10 is %d", oneFrom(10));  
    7. // 打印出: "1 from 10 is 9"  
    8. // 这个block函数distanceTraveled)传入3个float型参数,返回float值。   
    9.  
    10. float (^distanceTraveled) (float, float, float) =  
    11.  
    12.                           ^(float startingSpeed, float acceleration, float time) {  
    13.     float distance = (startingSpeed * time) + (0.5 * acceleration * time * time);  
    14.     return distance;  
    15. }; 


      你也可以传入一个Block作为一个参数,而不要以如上的方式声明它们,这样就可以在需要将block作为参数的时候以内联代码的方式简单地实现。

  • NSArray *anArray = [NSArray arrayWithObjects: @"cat", @"dog",nil];  
  • sortFunction(anArray, ^(string *a string *b){  
  • if ( a == @"cat"return TRUE; }); 

  • 这样我们就看到一个内联的block代码段占据了最后一个参数(必须是参数列表的最后一个参数)的位置。Cocoa提供了很多使用Block的方法,这样你就可以传入Block作为方法的参数:

  • NSArray *array = [NSArray arrayWithObjects: @"A", @"B", @"C",  nil];  
  • NSSet *filterSet = [NSSet setWithObjects: @"A", @"Z", @"Q", nil];  
  •  
  • BOOL (^test)(id obj, NSUInteger idx, BOOL *stop); //Block declaration returns BOOL, params inc. id and BOOL  
  • //body of block gets the block literal ^(id obj, Bool *stop)... and the body logic   
  • test = ^ (id obj, BOOL *stop) {  
  •     if (idx < 5) {  
  •         if ([filterSet containsObject: obj]) {  
  •             return YES;  
  •         }  
  •     }  
  •     NO;  
  •  
  • }; 
  • Apple提供的另外一个例子是:

  • __block BOOL found = NO;  
  • NSSet *aSet = [NSSet setWithObjects: @"Alpha", @"Beta", @"Gamma", @"X", nil];  
  • Nsstring *string = @"gamma";  
  • //we provide below a way of how to enumerate, using our own compare logic  
  • [aSet enumerateObjectsUsingBlock:^(id obj, BOOL *stop) {  
  •     if ([obj localizedCaseInsensitiveCompare:string] == NSOrderedSame) {  
  •         *stop = YES;  
  •         found = YES;  
  •     }  
  • }]; 
  • 掌握它需要一点时间,但一旦领会了还是很简答的,是不?我建议大家看下Apple的文档,并看看其中引用到的一些API以确认下它们是如何使用的。多练习,熟能生巧!

    版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

    相关推荐