Block:带有自动变量的匿名函数。匿名函数:没有函数名的函数,一对{}包裹的内容是匿名函数的作用域。自动变量:栈上声明的一个变量不是静态变量和全局变量,是不可以在这个栈内声明的匿名函数中使用的,但在Block中却可以。虽然使用Block不用声明类,但是Block提供了类似Objective-C的类一样可以通过成员变量来保存作用域外变量值的方法,那些在Block的一对{}里使用到但却是在{}作用域以外声明的变量,就是Block截获的自动变量。
一、Block的语法及基本使用
二、 Block访问外部变量
1、 Block内部访问外部局部变量,Block内部会创建一个新的const变量,并把外部变量的值传给新变量。新的变量值不能被修改,同时外部变量值变化也不会影响到新的变量。
2、 Block内部访问外部静态变量,Block内会创建一个指向静态变量的指针,Block内外访问的是同一块内存,因此在Block内部可以对外部静态变量进行修改,同时外部变量修改也会影响到Block内部的值。
3、 Block内部访问外部局部变量时,在变量前面加上__Block修饰一下,Block内部就会想访问静态变量一样,创建一个指针指向外部局部变量,结果参照静态变量。从内存的角度来看,局部变量在栈上,使用__block修饰局部变量后,block会把局部变量复制一份到堆中,并让栈上的变量也指向堆中的新变量,此时在block内部和外部就访问了同一块内存,避免了局部变量在block执行之前就被释放,延长了局部变量的生命周期。
[if !supportLists]4、 [endif]Block内部访问全局变量,由于其作用域是全局的因此可以直接在Block内部直接使用全局变量。Block内部可以修改全局变量,同时全局变量在Block外部修改时,也会影响到Block内部的值。
三、 Block分为哪几种?为什么要用copy修饰?
Block按照它存在的内存区分为栈块、堆块、全局块。
1、 全局块:block内部没有访问外部变量,这个block就会被存放在全局区,成为全局块;
2、 堆块:存在于堆中,程序员自己管理生命周期;
3、 栈块:存在于栈中,在超出作用域之后就会被自动销毁,这样可能会导致在block调用前,block就被自动销毁了,因此,为了延长block的生命周期,ARC情况下会自动将栈块复制到堆中,并让原来的栈块生成一个指针指向新的堆块。
使用copy修饰符的作用就是将block从栈区拷贝到堆区。
四、循环引用
https://www.jianshu.com/p/14efa33b3562
http://www.cocoachina.com/ios/20170503/19165.html
https://www.jianshu.com/p/d28a5633b963