聊聊OC 中的Block
来源:互联网 发布:java程序格式 编辑:程序博客网 时间:2024/05/16 10:49
1.blcok的概念:
闭包是一个函数或指向函数的指针 + 该函数执行的外部的上下文变量; block 实际上就是 Objective-C 语言对于闭包的实现,在调用时才执行block中代码.
2.block 的底层解析
见博文http://www.jianshu.com/p/51d04b7639f1
总而言之, block就是一个里面存储了指向函数体中包含定义block时的代码块的函数指针,以及block外部上下文变量等信息的结构体。
block底层结构里包含了isa指针(包含isa指针的皆为对象),所以block也是一个对象,(runtime里面,对象和类都是用结构体表示)
3.block 的类型
block的常见类型有3种:
- _NSConcreteGlobalBlock (全局)
- _NSConcreteStackBlock (栈)
- _NSConcreteMallocBlock (堆)
NSConcreteGlobalBlock和NSConcreteStackBlock
// 全局blcokvoid (^globalBlock)() = ^{}; int main(int argc, const char * argv[]) { @autoreleasepool { //栈上block void (^stackBlock1)() = ^{ }; } return 0;}
底层结构中全局block的isa指向_NSConcreteGlobalBlock,即在全局区域创建,编译时具体的代码就已经确定在上图中的代码段中了,block变量存储在全局数据存储区;
而栈上block的isa指向了_NSConcreteStackBlock,即在栈区创建.
_NSConcreteStackBlock
堆中的block无法直接创建,其需要由_NSConcreteStackBlock类型的block拷贝而来(也就是说block需要执行copy操作后才能存放到堆中).
4.捕捉变量对block结构的影响
- 局部变量
- (void)test{ int a; ^{a;};}
block结构体中增加了一个int类型的变量,用来存储外部变量a,这次拷贝是一次值传递,并且要在block中对其进行操作将会发生错误:
^{a = 10;}; //block中不能修改局部变量
编译器会报错:Variable is not assignable (missing __block type specifier)
2.全局变量
// 全局静态static int a;// 全局int b;- (void)test{ ^{ a = 10; b = 10; };}
因为全局变量都是在静态数据存储区,在程序结束前不会销毁,所以block直接访问对应变量, 不进行拷贝等操作.
3.局部静态变量
- (void)test{ static int a; ^{ a = 10; };}
静态局部变量也是存储在静态数据储存区域的,也程序拥有一样的声明周期,也就是说在程序运行时,都能够保证block访问到一个有效的变量,但是其作用范围还是局限于定义它的函数中,所以需要通过静态局部变量的地址来进行访问.
4._block修饰的变量
- (void)test{ __block int a; ^{ a = 10; };}
当block被copy到堆中时,会将 a 也拷贝到堆中,所以即使局部变量所在堆被销毁,block依然能对堆中的局部变量进行操作.
总结:
1. 对于block外的变量引用,block默认是将其复制到其数据结构中来访问的 (只可读不可修改)
2. 对于用_block 修饰的外部变量引用,block是复制其引用地址来实现访问的.
思考:
-(void)test { int a = 10; __block int b = 20; void (^block1)() = ^() { NSLog(@"a=%d,b=%d",a,b); }; a = 30; b = 40; block1();}//结果输出什么?
结果为: a=10,b=40
答:虽然我们在调用block1之前改变了a的值,但是输出的还是Block编译时候a的值,所以截获瞬间自动变量就是:在Block中会保存变量的值,而不会随变量的值的改变而改变.
而b被__block 关键字修饰, 传递的指针, b的值会跟着源变量值得变化而变化,知道调用前才确定,所以结果为40.
如果不妥当之处,欢迎各位大神指正.
- 聊聊OC 中的Block
- oc中的block,认识block
- OC中的block数据类型
- OC语言中的block
- OC中的Block属性
- OC中的block语法
- OC中的Block,多态
- OC中的block
- OC中的Block
- OC中的block
- OC 中的 block
- OC 中的3种BLOCK
- OC中的Block简单介绍
- OC中的block使用初探
- OC中的block和protocol
- OC中的block闭包性问题
- OC语言中的block数据类型
- OC语言中的block数据类型
- JavaScript屏蔽Backspace键返回上个页面方法
- 26-group by的总结
- ie与firefox 的区别以及event的区别
- 第十五周OJ(7)判断字符串是否为回文
- gcc升级日记
- 聊聊OC 中的Block
- 【Unity】总结 unity遇到的一些坑
- pyton3 str()于bytes()
- 项目管理---git----快速使用git笔记(六)------本地开发与远程仓库的交互----常用git命令
- 【BZOJ 1691】[Usaco2007 Dec]挑剔的美食家 treap+贪心
- 12-Mac中的一些命令
- 用小于等于n元去买100只鸡,大鸡5元/只,小鸡3元/只,还有一种1/3元/只得小鸡,分别记为下,x,y,z只,编程求解x,y,z所有可能解
- 微信小程序开发之下拉刷新 上拉加载
- 13-mac中ssh的操作