什么是Blocks

Blocks是C语言的扩充功能。可以概括为:带有自动变量(局部变量)的匿名函数。

所谓的匿名函数,就是没有名字的函数,在C语言中是不允许的。
在计算机科学中,这种概念也称为:“闭包Closure”、“lambda计算”等。

而且一般而言,函数或者方法里是不能又出现一个函数的,但是Blocks作为一种数据类型,是可以的。通常Blocks用于封装代码。因为即便是写在函数体内部,不去调用它,就不会执行。

Blocks的声明

//无参数 无返回值void (^block1)(void) = ^void(void){NSLog(@"无参数 无返回值");};//无参数 无返回值 可省略表达void (^block2)(void) = ^{NSLog(@"无参数 无返回值");};//有参数 无返回值void (^block3)(NSString* name) = ^(NSString* name){NSLog(@"有参数 无返回值");};//有参数 无返回值 前面声明的参数名称可参略void (^block4)(NSString*) = ^(NSString* name){NSLog(@"有参数 无返回值");};//有参数 有返回值int (^block5)(NSString* name) = ^ int (NSString* name) {NSLog(@"有参数 有返回值");return 1;};int number = block5(@"haha");NSLog(@"howMuch : %d",number);

运行结果:

text2021[50774:5632858] 有参数 有返回值
text2021[50774:5632858] howMuch : 1

Blocks作为函数的参数

当Blocks作为参数时的书写格式比较怪异,要适应一下:
普通函数与Blocks函数对比:

- (void)block2:(NSString*)name{NSLog(@"name: %@",name);
}- (void)block3:(void(^)())callBackBlock{NSLog(@"调用了block3");callBackBlock();
}

block3是该Block的函数名称,后面的callBackBlock是Block后面所接的参数名称

其中,在参数(void(^)())中,
void(^)是指返回的参数列表,这里表示为无返回值。
() 内书写的是指传入的参数列表,这里表示无参数

我们可以注意到在Block3的方法里面,调用了callBackBlock()方法。
我们看看如何去调用Block3:

- (void)block4{NSLog(@"执行block4");[self block3:^{NSLog(@"我又回到block4");}];
}- (void)block3:(void(^)())callBackBlock{NSLog(@"调用了block3");callBackBlock();
}

运行结果:

text2021[51007:5682882] 执行block4
text2021[51007:5682882] 调用了block3
text2021[51007:5682882] 我又回到block4

由此可见,Blocks的作用就是改变原本代码的执行,如上述的结果,首先调用的是block4的方法,然后返回到block3处理了一下,再回到原来的地方接着处理block4.
它使得代码更加灵活。

带参数的Block回调

当有参数有返回值的blocks作为函数的参数的时候,写法更是复杂难记,但在开发中是十分常见的,因此只要熟悉、适应了就好。

- (void)block6{NSLog(@"执行block6");int spend = 5000;   //花费5000元//计算人均需要AA多少钱[self calculateInfo:^(int count, CGFloat discount) {NSLog(@"我又回到block6");CGFloat aa = spend / count * discount;NSLog(@"人均花费:%.2f",aa);}];
}- (void)calculateInfo:(void (^)(int count,CGFloat discount))callBackBlock{NSLog(@"执行calculateInfo");int count = 50;     //人数为50人CGFloat discount = 0.8; //折扣为8折callBackBlock(count,discount);
}

运行结果:

text2021[52299:5985655] 执行block6
text2021[52299:5985655] 执行calculateInfo
text2021[52299:5985655] 我又回到block6
text2021[52299:5985655] 人均花费:80.00

Blocks的作用:封装

假设:有一个人类,每天的事情大部分都是千篇一律的,无非就是睡觉、吃饭、工作、学习、谈恋爱等等,虽然大部分相同,但也总是有些差异的。
如果将该人类的每一天要做的事情写成代码,大致上就是:

第一天:起床 吃饭 工作 吃饭 睡觉
第二天:起床 吃饭 谈恋爱 吃饭 睡觉
第三天:起床 吃饭 学习 吃饭 睡觉

那么我们可以发现三天里只有中间部分环节是不同的,显然如果这样编写代码,是效率非常低的,而Blocks就能解决这样的问题。
代码:

- (void)block7{[self date:@"day1" Daily:^{NSLog(@"工作");}];[self date:@"day2" Daily:^{NSLog(@"谈恋爱");}];[self date:@"day3" Daily:^{NSLog(@"学习");}];
}- (void)date:(NSString*)date Daily:(void (^)(void))somethingDifferent{NSLog(@"%@",date);NSLog(@"起床");NSLog(@"吃饭");somethingDifferent();NSLog(@"吃饭");NSLog(@"睡觉");
}

运行结果:

text2021[55174:6433382] day1
text2021[55174:6433382] 起床
text2021[55174:6433382] 吃饭
text2021[55174:6433382] 工作
text2021[55174:6433382] 吃饭
text2021[55174:6433382] 睡觉
text2021[55174:6433382] day2
text2021[55174:6433382] 起床
text2021[55174:6433382] 吃饭
text2021[55174:6433382] 谈恋爱
text2021[55174:6433382] 吃饭
text2021[55174:6433382] 睡觉
text2021[55174:6433382] day3
text2021[55174:6433382] 起床
text2021[55174:6433382] 吃饭
text2021[55174:6433382] 学习
text2021[55174:6433382] 吃饭
text2021[55174:6433382] 睡觉

Blocks中的变量传递

在Blocks中我们可以使用局部变量,是因为从Blocks外部传递进来的局部变量,Block会视为是一个常量(不可改变的量),只读不可写。
如果要在Blocks内修改该局部变量,需要为该变量做一个__block 的声明,这样的话,编译器才会吧该变量的地址传进去block中。

- (void)block8{int number = 10;void (^test)(void) = ^{//只是声明Block,不会被调用NSLog(@"%d",number);//可读number = 20;};test(); //调用Blocks
}

应改为:

 __block int number = 10;void (^test)(void) = ^{NSLog(@"%d",number);//可读number = 20;};test();

另注意:在block内部使用对象的时候,会对对象有一个强引用,因此,如果在block中调用到Self的话,self就会因为block的调用,而自动计数+1,但却不一定会造成循环引用,这个情况还得具体情况具体分析

OC基础 Block相关推荐

  1. OC基础--block

    block与函数类似:1.可以保存代码 2.又返回值 3.有形参 4.调用方式一样 block的标志:^ 一.定义一个无参无返回值的block void (^myBlock)();--1.void 代 ...

  2. IOS开发基础之OC的Block入门_Day09-Block

    IOS开发基础之OC的Block入门_Day09-Block block是oc的重要的基础知识,重点之重.跟协议一样重要,是进行函数回调重要手段.在后续的UI学习具有举足轻重的地位.学会基础的bloc ...

  3. OC语言Block和协议

    OC语言Block和协议 分类: OC基础2014-10-07 09:24 162人阅读 评论(0) 收藏 举报 OC Block OC协议 OC语言BLOCK和协议 一.BOLCK (一)简介  B ...

  4. iOS开发面试知识整理 – OC基础 (二)

    iOS | 面试知识整理 – OC基础 (二) 1.C和 OC 如何混编 xcode可以识别一下几种扩展名文件: .m文件,可以编写 OC语言 和 C 语言代码 .cpp: 只能识别C++ 或者C语言 ...

  5. OC基础第四讲--字符串、数组、字典、集合的常用方法

    OC基础第四讲--字符串.数组.字典.集合的常用方法 字符串.数组.字典.集合有可变和不可变之分.以字符串为例,不可变字符串本身值不能改变,必须要用相应类型来接收返回值:而可变字符串调用相应地方法后, ...

  6. OC基础回想(十二)协议

    在OC基础(十一)中我们讨论了类别和非正式协议的奇异之处.在使用非正式协议时.能够仅仅实现你想要获得响应的方法.也不必在对象中声明不论什么内容来表示该对象可用作托付对象. 全部这些任务能够用最少的代码 ...

  7. OC基础 代理和协议

    OC基础 代理和协议 1.协议 (1)oc语言中得协议:一组方法列表,不需要我们自己实现,由遵守协议的类来实现协议所定制的方法. (2)协议的使用步骤:制定协议-->遵守协议-->实现协议 ...

  8. OC语言Block 续

    OC语言 Block 转载:http://blog.csdn.net/weidfyr/article/details/48138167 1.Block对象中的变量行为 结论: 在block代码块内部可 ...

  9. OC基础1:一些基本概念

    "OC基础"这个分类的文章是我在自学Stephen G.Kochan的<Objective-C程序设计第6版>过程中的笔记. 1.关于类方法和实例方法: (1).类方法 ...

最新文章

  1. [USACO1.3]修理牛棚 Barn Repair
  2. linux设置send时间,[转]Socket 的send,recv在windows与linux下的超时设置
  3. Git学习(二)远程仓库建立与克隆
  4. canvas+websocket+vue做一个你画我猜小游戏
  5. 啊哈添柴挑战Java1491. 奔跑的小人
  6. Python3爬虫(4)--抓取考生的四六级成绩
  7. 计算机网络思维导图图片
  8. 苹果产品介绍合集(加广告语和官方介绍)第二版--由Apple_VM_Xiaoqie整理(微信,抖音同号)
  9. 回望过去,感觉现在的自己十分功利
  10. [转载]tensorflow二次开发
  11. 180721 逆向-极客巅峰(Re)
  12. Python开发-flask框架学习
  13. h3c登录交换机的配置方法
  14. 【妄言之言】我的2016--困境与选择
  15. java去除图片水印的解决办法
  16. 计算机班级平均分分类汇总,使用分类汇总汇总平均分.docx
  17. 马云说的到底对不对,京东到底行不行?
  18. jQuery实现小游戏飞机大战
  19. Chrome太占内存怎么办?试试这个
  20. 酒店预订app的前景优势

热门文章

  1. 【3】Ubuntu18.04下载与安装,以及中文输入法的安装
  2. 开发者数据库规范 - 团队协作
  3. 正点原子 核心板IMX6ULL IIC RTC驱动 PCF8563
  4. 想做数码管显示,单片机IO口资源不够?看看WTV890语音芯片能做些啥
  5. 京东茅台抢购方法,与黄牛站在同一起跑线
  6. vue地图单个打点定位
  7. 易语言之ocr自动识别验证码dll文件
  8. 杰理之BQB 的 profile 测试【篇】
  9. 5089. 安排会议日程
  10. matlab如何使用源代码,rosenbrock函数的matlab源程序代码是怎么样的?