block的相关记录
block在创建的时候,它的内存是分配在栈上的,所以说block本身的作于域是属于创建时候的作用域,一旦在创建时候的作用域外面调用block将导致程序崩溃。因为栈区的特点就是创建的对象随时可能被销毁,一旦被销毁后续再次调用空对象就可能会造成程序崩溃,用copy修饰,把block从栈中拷贝到堆中,防止被释放。
block有3种类型:
_NSConcreteGlobalBlock:全局的静态 block,类似函数。如果block里不获取任何外部变量。或者的变量是全局作用域时,如成员变量、属性等; 这个时候就是Global类型
_NSConcreteStackBlock:保存在栈中的 block,栈都是由系统管理内存,当函数返回时会被销毁。__block类型的变量也同样被销毁。为了不被销毁,block会将block和_block变量从栈拷贝到堆。
_NSConcreteMallocBlock:保存在堆中的 block,堆内存可以由开发人员来控制。当引用计数为 0 时会被销毁。
block使用时的注意事项
1.block访问局部变量时,相当于是值拷贝,不能修改只能访问
2.当局部变量被__block修饰时,相当于block也引用了这个外部的值,这个值是可以修改的
3.全局变量是可以在block中修改的。
block的相关疑问
1.为什么局部变量的值要用__block修饰才能在block里面被修改?
因为局部变量的值在出了作用域时就会被销毁,但被_block修饰的时候,相当于block引用了它,所以就不会被释放了
2.block 里 strong self 后,block 不是也会持有 self 吗?而 self 又持有 block ,那不是又循环引用了?
在block里用strong引用,保证了持有引用的周期只在 block被执行时,闭包函数返回后就释放了。而直接用强引用,持有引用的周期则是block的生命周期,就会循环引用了。
3.为什么block不用strong修饰符 而是copy?
strong修饰的block,系统默认的处理方式也是copy。 但是为了保证行为和修饰符一样,所以建议使用copy的修饰符。
4.为什么@strongify(self) 和 @weakify(self) 要配套使用?
因为这样可以防止我们在block中使用self时,self出现提前释放的问题。我们在block中使用strongify(self)就能保证在这个block的回调执行完之前self是不会被释放的。
网友评论