黑马程序员---OC学习笔记之block访问外部变量【重点面试】
来源:互联网 发布:海尔ife矩阵 编辑:程序博客网 时间:2024/04/30 20:21
1、block可以访问外部变量么?
当block时,如果里面用到外部变量,会先把外部变量从栈区【以const的方式拷贝】到【堆区(block是对象,一般在堆区)】。因此可以访问外部变量的值,但是无法改变外部变量的值。
【例如】
//定义一个外部变量 int sum = 2; //定义一个有参有返回值的block的别名 typedef int (^myBlock)(int, int); //此时myBlock是一个类型,不再是一个单纯的变量了 NSLog(@"sum = %p",&sum);//此时sum在栈区 //当block时,如果里面用到外部变量,会先把外部变量从栈区【以const的方式拷贝】到【堆区(block是对象,一般在堆区)】。 myBlock b1 = ^(int a, int b){ NSLog(@"sum = %p",&sum);//此时的地址不在栈区,而在堆区 //sum = a + b;//不能改变sum的值,会报错 //可以外部变量sum的值 return sum + a + b; }; NSLog(@"sum = %p",&sum);//此时sum在栈区 NSLog(@"a + b = %d", b1(1,2)); NSLog(@"sum = %p",&sum);//此时sum在栈区
【打印结果】
2015-10-07 14:54:41.216加强02[1308:303] sum =0x7fff5fbff93c
2015-10-07 14:54:41.218加强02[1308:303] str =0x7fff5fbff930
2015-10-07 14:54:41.219加强02[1308:303] sum =0x7fff5fbff93c
2015-10-07 14:54:41.219加强02[1308:303] sum =0x100102e40
2015-10-07 14:54:41.219加强02[1308:303] a + b = 5
2015-10-07 14:54:41.220加强02[1308:303] sum =0x7fff5fbff93c
2、在block中能否定义新的变量
可以,而且在block内部定义的变量是在【栈区】分配空间的
【例如】
//定义一个外部变量 int sum = 2; //定义一个有参有返回值的block的别名 typedef int (^myBlock)(int, int); NSLog(@"sum = %p",&sum);//此时sum在栈区 myBlock b1 = ^(int a, int b){ int sum = 100; NSLog(@"内部sum = %p",&sum);//此时的地址在栈区 return sum + a + b; }; NSLog(@"a + b = %d", b1(1,2)); NSLog(@"外部sum= %p",&sum);//此时sum在栈区
打印结果:
2015-10-07 15:15:29.382加强02[1339:303] sum =0x7fff5fbff93c
2015-10-07 15:15:29.384加强02[1339:303]内部sum = 0x7fff5fbff904
2015-10-07 15:15:29.384加强02[1339:303] a + b = 103
2015-10-07 15:15:29.385加强02[1339:303]外部sum = 0x7fff5fbff93c
3、如何做到在block内修改外部变量?
【可以】可以用__block修饰外部变量
//定义一个外部变量,__block使得这个变量能在block创建时不是以const方式拷贝,也就是说可以修改 __block int sum = 2; //定义一个有参有返回值的block的别名 typedef int (^myBlock)(int, int); NSLog(@"sum = %p",&sum);//此时sum在栈区 myBlock b1 = ^(int a, int b){ sum = 100;//此时就允许修改 NSLog(@"内部sum = %p",&sum);//此时的地址在栈区 return sum + a + b; }; NSLog(@"a + b = %d", b1(1,2)); NSLog(@"外部sum= %d address = %p",sum,&sum);//此时sum在栈区
【打印结果】
2015-10-07 15:20:17.928加强02[1358:303] sum =0x7fff5fbff938
2015-10-07 15:20:17.930加强02[1358:303]内部sum = 0x100301128
2015-10-07 15:20:17.930加强02[1358:303] a + b = 103
2015-10-07 15:20:17.931加强02[1358:303]外部sum = 100 address =0x100301128
【分析结果】
由结果可知,外部变量A在block创建时被【非const方式拷贝到堆区中】,此时在block中就可以修改这个外部变量A,而且,在这个block之后(即block的外面),外部变量A的值已经被改变,而且地址也是堆区地址。以后外部变量A将一直使用这个地址
4、注意事项
1)全局block
2)栈block
3)堆block
4)常量变量(NSString *a = @"abc"中a是变量,@“abc”是常量);不加__block类型修饰,block会引用常量的地址(浅拷贝)。加__block类型修饰block会去引用【常量变量】(如:a变量,a = @“abc”,可以任意修改a指向的内容)的地址
5)如果不加__block就直接在block内部修改外部的变量,编译器会报错,此时,block内部中外部变量是只读的。
- 黑马程序员---OC学习笔记之block访问外部变量【重点面试】
- ——黑马程序员——OC中block访问外部变量
- OC 重点block-------2-------block内部访问外部变量的问题
- 黑马程序员-----oc语言学习笔记之block和协议
- 黑马程序员---OC学习笔记之block的基本概念
- 黑马程序员---OC学习笔记之block的使用场景
- 黑马程序员:OC学习日记之block
- 黑马程序员---OC学习笔记之分类(Category)非正式协议【重点】
- 黑马程序员- IOS学习笔记-OC ARC、BLOCK、protocol
- 黑马程序员-OC学习笔记-----ARC和代码块block
- 黑马程序员——ios学习笔记 OC 协议&Block
- 黑马程序员-iOS基础之OC重点语法(Block、Protocol)
- 黑马程序员-OC学习日记六之Block小结
- 黑马程序员----OC学习笔记之NSArray
- 黑马程序员----oc加强笔记----block
- block访问外部变量
- block 访问外部变量
- block访问外部变量
- C#点击iframe页面的控件(button),弹出层,关闭弹出层时只刷新父页面中的iframe里面的页面
- javascript之,深扒typeof,instanceof操作符
- 关于链表的一些总结和代码,java实现
- mybatis中#{}与${}区别
- hdu 1061 Rightmost Digit
- 黑马程序员---OC学习笔记之block访问外部变量【重点面试】
- 深入理解Android之Gradle
- stm8 io口 spi模拟,可用于RC522
- UIStatusBar汇总_iOS9.0后修改状态栏颜色(UIStatusBar)
- IOS 启动画面设置
- R语言读取oracle数据库数据表
- 数据输入控件使用简介
- iOS开发--点击屏幕获得屏幕坐标
- 排量与油耗