文档章节

blick的使用

YunHe_Lee
 YunHe_Lee
发布于 2015/06/17 11:45
字数 938
阅读 0
收藏 0
点赞 0
评论 0

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声明为一个变量,所以可以将它当做一个函数中使用:


  
  1. NSLog(@"%d", aBlock(49)); //adds 49 to 7 which gives us 56.  

我们刚看过了将block当做变量的情况,但通常情况下我们会以内联的方式使用Block,比如在一个变量中。API要么会使用Block在一个对象集合上执行某种操作,要么将其作为一个操作完成后的回调。


  
  1. NSComperator compareStringsBlock = ^(id stringA, id stringB) {  
  2. NSRange rangeS  = NSMakeRange (0, [stringA length]);  
  3.   return (stringA compare:stringB options:comparisonOptions range:rangeS locale:currentLocale];  
  4. };  
  5.  
  6. 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作为参数的时候以内联代码的方式简单地实现。


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


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


  
  1. NSArray *array = [NSArray arrayWithObjects: @"A", @"B", @"C",  nil];  
  2. NSSet *filterSet = [NSSet setWithObjects: @"A", @"Z", @"Q", nil];  
  3.  
  4. BOOL (^test)(id obj, NSUInteger idx, BOOL *stop); //Block declaration returns BOOL, params inc. id and BOOL  
  5. //body of block gets the block literal ^(id obj, NSUInteger idx, Bool *stop)... and the body logic   
  6. test = ^ (id obj, NSUInteger idx, BOOL *stop) {  
  7.     if (idx < 5) {  
  8.         if ([filterSet containsObject: obj]) {  
  9.             return YES;  
  10.         }  
  11.     }  
  12.     return NO;  
  13.  
  14. }; 

Apple提供的另外一个例子是:


  
  1. __block BOOL found = NO;  
  2. NSSet *aSet = [NSSet setWithObjects: @"Alpha", @"Beta", @"Gamma", @"X", nil];  
  3. NSString *string = @"gamma";  
  4. //we provide below a way of how to enumerate, using our own compare logic  
  5. [aSet enumerateObjectsUsingBlock:^(id obj, BOOL *stop) {  
  6.     if ([obj localizedCaseInsensitiveCompare:string] == NSOrderedSame) {  
  7.         *stop = YES;  
  8.         found = YES;  
  9.     }  
  10. }]; 

掌握它需要一点时间,但一旦领会了还是很简答的,是不?我建议大家看下Apple的文档,并看看其中引用到的一些API以确认下它们是如何使用的。多练习,熟能生巧!

原文出处:http://answers.oreilly.com/topic/2281-how-to-use-blocks-with-ios/

© 著作权归作者所有

共有 人打赏支持
YunHe_Lee
粉丝 0
博文 8
码字总数 4263
作品 0
朝阳

暂无文章

mysql 主从复制中遇到的错误!

。。。。。

万建宁
8分钟前
0
0
DUBBO 详细介绍

摘要: 主要核心部件: Remoting: 网络通信框架,实现了 sync-over-async 和 request-response 消息机制. RPC: 一个远程过程调用的抽象,支持负载均衡、容灾和集群功能 Registry: 服务目录框架...

明理萝
18分钟前
0
1
4 个快速的 Python 编译器 for 2018

简评:Python 和其他的解释型语言一样经常被吐槽性能不行,所以开发人员为了提升性能创建了不少编译器,本文则选取其中的四个做了基准测试。 Python 其实是一种相当快的语言,但它并不像编译...

极光推送
22分钟前
0
0
spring boot注册多个MQ服务器的问题

关于注册到多个MQ源的文章已经有很多了,这里记录一下声明queue的坑; 如果使用注册bean的方式声明queue,会导致声明的queue同时被注册到所有的MQ源上; //如果使用下面的声明方式,que...

placeholder
23分钟前
0
0
Java面试基础篇——第九篇:BIO,NIO,AIO的区别

现在IO模型主要分三类:BIO(同步阻塞IO),NIO(同步非阻塞IO),AIO()。 先来看看BIO。 1. BIO 服务端接受到请求后,要指派或新建一个线程去处理客户端的IO请求,直到收到断开连接的指令。这么做...

developlee的潇洒人生
28分钟前
0
0
@RequestMapping @ResponseBody 和 @RequestBody 用法与区别

1.@RequestMapping 国际惯例先介绍什么是@RequestMapping,@RequestMapping 是一个用来处理请求地址映射的注解,可用于类或方法上。用于类上,表示类中的所有响应请求的方法都是以该地址作为...

特拉仔
30分钟前
1
0
基于 HTML5 结合互联网+ 的 3D 隧道

前言 目前,物资采购和人力成本是隧道业发展的两大瓶颈。比如依靠民间借贷,融资成本很高;采购价格不透明,没有增值税发票;还有项目管控和供应链管理的问题。成本在不断上升,利润在不断下...

xhload3d
32分钟前
0
0
济南小程序热度分析

原文链接:http://www.jnqianle.cn/company/2072.html

tianma3798
33分钟前
1
0
大数据软件

beats 采集 kafka spark hive es grafana zeppelin

ArlenXu
35分钟前
0
0
Mac item2常用快捷键

标签 新建标签:command + t 关闭标签:command + w 切换标签:command + 数字 command + 左右方向键 切换全屏:command + enter 查找:command + f 分屏 水平分屏:command + d 垂直分屏:c...

说回答
38分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部