~ block的本质?
封装了函数调用以及调用环境(上下文)的OC对象。
block本质也是一个OC对象,它内部也有个isa指针。
~ block的变量捕获(capture)
为了保证block内部能够正常访问外部的变量,block有个变量捕获机制。
局部变量 auto 捕获到block内部,访问方式:值传递。
局部变量 static 捕获到block内部,访问方式:指针传递。
全局变量不捕获,访问方式:直接访问。
~ 在block内如何修改block外部变量?
默认情况下,在block中访问的外部变量是复制过去的,即写操作不会对原变量生效。
1.使用__blcok 修改block外部变量,使用了 __blcok 之后,在 block 被 copy 到堆上的同时也会将捕获的外部变量 copy 到堆上,之后便可以在 block 内部对外部变量进行修改。
~ __block的作用是什么?
修改外部变量。
__block不能修饰全局变量,静态变量。
编译器会将__block变量包装成一个对象。
__block int a;
void(^blockAction)(void) = ^{ a = 10};
blockAction();
~ __block的内存管理?
当block在栈上时,并不会对__block变量产生强引用。
当block被copy堆上时,会调用block内部的copy函数,copy函数内部会调用_Block_object_assign函数,_Block_object_assign函数会对__block变量形成强引用。
当block从堆中移除时,会调用block内部的dispose函数,dispose函数内部会调用_Block_object_dispose函数,_Block_object_dispose函数会自动释放引用的__block变量。
~ block的属性修饰词为什么是copy?block是否可以用strong修饰?
因为block变量默认是声明为栈变量的,为了能够在block的声明域外使用,所以要把block拷贝(copy)到堆,block一旦没有进行copy操作,就不会在堆上。
可以。用copy,strong修饰block在ARC和MRC都是可以的,都是在堆区
~ block类型
_NSConcreteGlobalBlock 全局的静态 block,不会访问外部局部变量,执行完就销毁。
_NSConcreteStackBlock 保存在栈中的 block,当函数返回时会被销毁。和第一种的区别就是调用了外部变量。
_NSConcreteMallocBlock 保存在堆中的 block,当引用计数为 0 时会被销毁。例如按钮的点击事件。
~ 使用block时什么情况会发生循环引用,怎么解决?
一个对象中强引用了block,并且在block中又使用了该对象,就会发生循环引用。解决方法:将该对象使用__weak或者__Block来修饰,修饰之后再在block中使用。
id weak weakSelf = self; 或者weak__typeof(&*self)weakSelf = self;或者 id__block weakSelf =self;
~ 什么时候在block里进行强引用?
在Block结构体中看到,Block本身对self的引用仍然只是弱引用,并不造成引用循环。strongSelf只存在于Block对应的函数,函数执行完它立刻就被释放了。
函数执行过程中self变为nil了,那么函数一开始声明的strongSelf会暂时持有着self,此时会有一个暂时的引用循环。当函数执行完(即是Block执行完),strongSelf超出作用域被释放.
~什么时候不需要弱引用weak?
Block技巧与底层解析
Block内的强引用
谈 Objective-C block 的实现
block的修饰词为什么选用copy
网友评论