OC中的block闭包性问题
来源:互联网 发布:云警联网报警主机编程 编辑:程序博客网 时间:2024/06/05 14:35
学习了OC中的block代码段的用法,非常的好用,功能有些类似于一个函数指针,又可以作为一块代码段。
学习了其中的闭包性,记一下:
在block内部,可以像普通函数一样访问数据:局部变量、传递给block的参数,全局变量/函数。并且由于block具有闭包性,所以还能访问非局部变量(non-local variable)。非局部变量定义在block之外,但是在block内部有它的作用域。例如,getFullCarName可以使用定义在block前面的make变量:
- NSString *make = @"Honda";
- NSString *(^getFullCarName)(NSString *) = ^(NSString *model) {
- return [make stringByAppendingFormat:@" %@", model];
- };
- NSLog(@"%@", getFullCarName(@"Accord")); // Honda Accord
非局部变量会以const变量被拷贝并存储到block中,也就是说block对其是只读的。如果尝试在block内部给make变量赋值,会抛出编译器错误。
以const拷贝的方式访问非局部变量,意味着block实际上并不是真正的访问了非局部变量——只不过在block中创建了非局部变量的一个快照。当定义block时,无论非局部变量的值是什么,都将被冻结,并且block会一直使用这个值,即使在之后的代码中修改了非局部变量的值。下面通过代码来看看,在创建好block之后,修改make变量的值,会发生什么:
- NSString *make = @"Honda";
- NSString *(^getFullCarName)(NSString *) = ^(NSString *model) {
- return [make stringByAppendingFormat:@" %@", model];
- };
- NSLog(@"%@", getFullCarName(@"Accord")); // Honda Accord
- // Try changing the non-local variable (it won't change the block)
- make = @"Porsche";
- NSLog(@"%@", getFullCarName(@"911 Turbo")); // Honda 911 Turbo
block的闭包性为block与上下文交互的时候带来极大的便利性,当block需要额外的数据时,可以避免使用参数——只需要简单的使用非局部变量即可。
修改非局部变量
冻结中的非局部变量是一个常量值,这也是一种默认的安全行为——因为这可以防止在block中的代码对非局部变量做了意外的修改。那么如果我们希望在block中对非局部变量值进行修改要如何做呢——用__block存储修饰符(storage modifier)来声明非局部变量:
- __block NSString *make = @"Honda";
这将告诉block对非局部变量做引用处理,在block外部make变量和内部的make变量创建一个直接的链接(direct link)。现在就可以在block外部修改make,然后反应到block内部,反过来,也是一样。
通过引用的方式访问非局部变量
这跟普通函数中的静态局部变量(static local variable)类似,用__block修饰符声明的变量可以记录着block多次调用的结果。例如下面的代码创建了一个block,在block中对i进行累加。
- __block int i = 0;
- int (^count)(void) = ^ {
- i += 1;
- return i;
- };
- NSLog(@"%d", count()); // 1
- NSLog(@"%d", count()); // 2
- NSLog(@"%d", count()); // 3
0 0
- OC中的block闭包性问题
- oc中的block,认识block
- OC中的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数据类型
- bloomfitler 解决大数据查询问题
- pat1047
- private[spark] class SparkDriverExecutionException 中的[spark]是限制private的范围
- 页游开发客户端as3常用的开源类
- ip为 : 202.76.52.142/30 怎么看?
- OC中的block闭包性问题
- Ansible Tryout
- 线程简介
- Shader实例 : 雪景效果
- 趣写算法系列之--匈牙利算法
- HDU ACM 1257 最少拦截系统
- 基于平均法线实现顶点网格变形控制的总结
- AnimationDrawable在listview中的播放--android实用技巧
- STL源码剖析 - 第4章 序列式容器 - queue