黑马程序员---OC学习笔记之block访问外部变量【重点面试】
2015-10-08 15:07
447 查看
------Java培训、Android培训、iOS培训、.Net培训--------
1、block可以访问外部变量么?
当block时,如果里面用到外部变量,会先把外部变量从栈区【以const的方式拷贝】到【堆区(block是对象,一般在堆区)】。因此可以访问外部变量的值,但是无法改变外部变量的值。
【例如】
【打印结果】
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内部定义的变量是在【栈区】分配空间的
【例如】
打印结果:
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修饰外部变量
【打印结果】
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内部中外部变量是只读的。
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基础---类方法的总结
- 重庆的程序员,我今天遇到个好事,告诉大家一下!
- 关于职业生涯规划的会议记录
- 职场新人,你进入职场应该规划的事
- 程序员鼓励师到底是啥?
- 【扣丁学堂】谁说企业没人要老程序员
- 论c程序员转java学习
- PHP程序员应该知道的15个库
- 程序员,你需要些“脑力运动”了
- 50个Java多线程面试题
- 嫁给程序员的十大好处
- 各大互联网公司2014前端笔试面试题–HTML,CSS篇
- 面试题——Hibernate中Inverse和Cascade的区别
- 黑马程序员---OC学习笔记之block的基本概念
- 黑马程序员---OC学习笔记之分类(Category)延展
- 黑马程序员---OC学习笔记之分类(Category)非正式协议【重点】
- 黑马程序员---OC学习笔记之分类(Catgory)的概念及使用
- 黑马程序员---OC学习笔记之ARC的概念及原理
- 黑马程序员---OC学习笔记之autorelease快速创建对象的应用
- 黑马程序员---OC学习笔记之autorelease注意及错误用法