iOS Block基础学习

1.什么是block?

block是将函数及其执行上下文封装起来的对象(底层有isa指针).

2.截获变量

1.对于基本数据类型的局部变量截获其值
2.对于对象类型的局部变量连同所有权修饰符一起截获、
3.以指针形式截获局部静态变量
4.不截获全局变量、静态全局变量

编译前
编译后.png
3.__block修饰符

一般情况下,对被截获变量进行赋值操作需添加__block修饰符

image.png
需要为array添加修饰符吗?

不需要,因为array对象的操作只有一个使用,没有赋值。只有赋值的操作,我们才需要加上__block修饰符。

image.png

需要在array声明的时候,加上__block修饰符。否则会编译报错。

image.png
image.png
image.png
  • 因为multiplier通过__block修饰之后,会变成一个对象。

__block修饰的变量变成了对象

image.png

image.png
4.block的内存管理?
image.png

image.png
image.png

栈上一个block。进行copy后,会在堆上有一个一样的block和__block变量,随着变量作用域结束,栈上的block销毁。在堆上的block仍然存在。如果在mrc环境下,会造成内存泄漏。

image.png

如果栈上的block进行了copy。会在堆上也有一份内容。实际上我们不是修改的栈上的__block的值。而是通过栈上的__forwarding指针找到堆上的__block变量。然后对堆上的值进行修改。

如果堆上的__block变量由于被成员变量的block持有的话。当在其他地方调用__block修改的时候。会通过自身的__forwarding修改的。

__forwarding存在的意义?

不论在任何内存位置,都可以顺利的访问同一个__block变量。

5.block真题。
image.png
image.png
image.png

4.
image.png

在MRC下,不会产生循环引用。
在ARC下,会产生循环引用,引起内存泄漏。


image.png

如果一直不调用_blk的话。这个循环引用的环会一直存在。

6. delegate,block的区别?

协议代理,block的区别

7.如何在block内如何修改block外部变量?

使用__block进行修改。
在block内如何修改block外部变量引发的思考

8.block中的循环引用是怎么造成的?

一个对象中强引用了block,在block中又强引用了该对象,就会发生循环引用。
苹果官方的建议是:传进block之前,把self转换成weak automatic的变量,这样在block中就不会出现对self的强引用。如果在block执行完成之前,self被释放,weakSelf也会置为nil。weak类型相对比较安全,因为可以在释放后自动置为nil,不会引起野指针。

9.为什么系统的UIView的动画,不需要处理循环引用问题?

原理: UIView调用的是类方法,当前控制器不可能强引用一个类 ,所以循环无法形成 --> 动画block不会造成循环引用的原因。

你可能感兴趣的:(iOS Block基础学习)