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方法!
(面试加分题)OC中block的基本用法与深入了解
最新推荐文章于 2021-11-02 18:26:44 发布