(面试加分题)OC中block的基本用法与深入了解

block的基本用法

block是一种数据类型,可以使一段代码块变成一个变量,格式和函数很像.

1,无参无返回: void (^myblock)() = ^(){  ...... };(无参的话前面小括号可以省略,后面分号不能少).

2,有参无返回: void (^myblock)(int,int) = ^(int a, int b){ .......};(有参数的话,'='号后面的形参名不能省).

3,无参有返回: int (^myblock)() = ^{.......return....};

4,有参有返回:int (^myblock)(int , int) = ^(int a ,int b){  ....return a+b;};

和函数不同的是block可以在内部访问外部的变量,但是不能给外部变量重新赋值,因为在内部使用的外部变量是copy的新的外部变量,内存位置不一样.

在block内部也可以定义和外部同名的变量,这样就会屏蔽外部变量的作用域,内部无法使用外部变量.

在默认的情况下,内部不能修改外部变量.当给外部的局部变量加上__Block修饰词,则内部可以改变该变量.

block的内存问题

因为存储的位置不同,block也分为三种:

1,全局block(__NSGlobalBlock__):类似函数,存储在代码区,ARC与MRC一样只要没有使用外部变量,就是全局block.

2,堆block(__NSMallocBlock__):存储在堆区的block,在ARC下使用了外部变量,就是堆block.在MRC下把栈block进行copy操作 就会得到堆block.

3,栈block(__NSStackBlcok__):存储在栈区的block,在MRC下使用了外部变量,就是栈block.

关于blcok中的面试题

面试第一问:在block内部能否使用外部变量? 能使用

面试第二问:block是如何使用外部变量的?

block使用外部变量并不是直接使用,而是把外部变量拷贝一份.在ARC下,外部变量被拷贝到堆区,而在MRC下外部变量被拷贝到栈区!

面试第三问:在block内部能否改变外部变量的值?

在ARC与MRC下,如果不做任何修饰都不可以,block内部使用的外部变量和外部的变量已经不是一个地址了.而block在使用外部变量时,会把外部变量以 const(不可更改)的格式拷贝一份使用!

面试第四问:如果要在block内部改变外部变量怎么办?

在定义外部变量的时候添加修饰词__Block,添加__Block的外部变量在blcok中不再以const的格式拷贝,而是都copy到堆区,__blcok的作用就是让系统忽视block中修改外部变量的问题!

面试第五问:当block在类中被声明时,例:@property(nonatomic,assgin) void (^myblock)();在MRC下,只要property的参数是assgin,不管有没有使用外部变量,都是栈block.而栈block因为内存不受程序员控制很容易发生内存泄露.

解决办法是,把参数换成copy或strong.

面试第六问:在MRC下,下面这段代码有没有问题?

答案是肯定的!因为在MRC下,用了外部变量的b1是一个栈block,而在栈区的代码只能在作用域内使用,所以bb接收不到test()的返回值.

通过上述操作可以解决这个问题.而在ARC中不会存在这个问题,因为编译器会自动在合适的位置添加retain和release方法!

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值