博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
ios 中使用 block
阅读量:7172 次
发布时间:2019-06-29

本文共 2752 字,大约阅读时间需要 9 分钟。

hot3.png

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

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

 
int num1 = 7;   int(^aBlock)(int) = ^)int num2) {      return num1+nunm2;   };  

在如上代码中我们将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声明为变量,并将其作为一个函数使用:
 

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

  你也可以传入一个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, NSUInteger idx, Bool *stop)... and the body logic    test = ^ (id obj, NSUInteger idx, BOOL *stop) {       if (idx < 5) {           if ([filterSet containsObject: obj]) {               return YES;           }       }       return 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以确认下它们是如何使用的。多练习,熟能生巧!

转载于:https://my.oschina.net/makeffort/blog/85519

你可能感兴趣的文章
Powershell AWS 自动化管理 (12) - 创建一个高可用的WordPress博客(下)
查看>>
postfix+mysql+courier-authlib+extmail+extman搭建企业邮箱
查看>>
品友互动:数据科学家来自实践
查看>>
EMC:重新定义自己
查看>>
OSSIM系统中Sensor的设置
查看>>
SCVMM2012部署之三:安装VMM自助服务门户
查看>>
支持多核smp squid3.2 缓存反向代理【ok】~
查看>>
一个Web页面的问题分析
查看>>
草根创业回忆录一: 踏出了第一步的时候...
查看>>
情景会话:请对产品提提意见好吗?
查看>>
Android应用程序组件Content Provider在应用程序之间共享数据的原理分析(5)
查看>>
使用组策略配置域中计算机注册表安全
查看>>
使用spotlight on unix监控linux主机
查看>>
【习惯的力量】之五让拖延见鬼去吧
查看>>
Twisted入门教程(13)
查看>>
Java通过FTP服务器上传下载文件的解决方案
查看>>
SVN “不能打开文件“.svn/lock” 权限不够”精解
查看>>
【给自己手机充值就送以下课程】
查看>>
RHEL6上安装nvidia显卡驱动
查看>>
分享Silverlight/WPF/Windows Phone一周学习导读(07月11日-07月17日)
查看>>