一、block基本使用

  声明:返回值(^block变量名)(参数)

  定义 :三种形式

 


二、block保存一段代码

      在某处在block内声明一段代码,在另一处调用


三、block传值

     正向传值:被传值者声明属性来接收值

     逆向传值:代理方法,委托方内声明协议

                    block逆向传值方法,传值者与接收值者只需三步


四、block循环引用

 block造成循环引用:block会对其块中的所有强指针变量都强引用一次,需弱化(有的需强化)

self.presentedViewController强引用了b控制器 ;b控制器[self dissmissViewController]

后,b控制器才会被释放 ==》 小岔知识点

   

block造成死循环:block代码块中,block会对里面的强指针变量都强引用一次,故若block块中若出现self,会造成死循环(block是self的属性,block属性的代码块中又强引用了self,故死循环)

block内部使用外部的一个对象,如果外部对象是强引用那么内部会自动生成一个强引用,引用着外部对象。如果外部对象时弱引用,那么内部会自动生成一个弱引用,引用着外部对象


五、block内存管理

外部局部变量 static修饰的局部变量  全局变量 __block修饰局部变量

retain copy:

非ARC下不copy的block会在栈中,ARC中的block都在堆上

block是一个对象,可以内存管理

 

 判断一个工程是否是ARC

 

 ARC管理原则:只要一个对象没有被强指针引用就会被销毁,默认局部变量对象都是强指针,存放于堆里边

 

 MRC开发常识:1.MRC中没有strong,weak 局部变量相当于基本数据类型,不会存放于堆里边,block即为基本数据类型

            2.MRC给成员属性赋值,不可以使用下划线方式,一定要用set方法(即使用self.属性)的方式赋值

 

 MRC:管理block

        总结:1,只要block块内没有引用外部局部变量,block就放在全局区

                 1.1 块内没有引用任何变量:<__NSGlobalBlock__: 0x10c8d3070>

                 1.2 块内引用非block块外的static修饰的局部变量:<__NSGlobalBlock__: 0x10e2d1070>(因为static修饰的局部变量的声明周期变大了)

                 1.3 块内引用块内的局部变量:<__NSGlobalBlock__: 0x10fc5b070>

                 1.4 块内引用块外__block修饰的局部变量:<__NSStackBlock__: 0x7fff552c69a0>(虽然被__block修饰,依旧引用的是局部变量)

                 1.5 块内引用全局变量:<__NSGlobalBlock__: 0x10c4e1070>

             2,只要block引用外部局部变量,block就被放在栈区 <__NSStackBlock__: 0x7fff56b149b8>

 

             3,block只能用copy修饰,不能使用retain,使用retain,block还是在栈里,会造成坏内存

 

             4, __block的作用:在block内修改快外局部变量的值,需要在声明此变量时用__block修饰此变量,才可修改

 ARC:

 ARC总结:

 1,只要block块内没有引用外部局部变量,block就放在全局区too:

   1.1 块内没有引用任何变量:<__NSGlobalBlock__: 0x10000c090> 全局区

   1.2 块内引用非block块外的static修饰的局部变量:<__NSGlobalBlock__: 0x106d89090> 全局区

   1.3 块内引用块内的局部变量:<__NSGlobalBlock__: 0x101b3f090> 全局区

   1.4 块内引用块外__block修饰的局部变量:<__NSMallocBlock__: 0x7fa818e0e990> 堆区

   1.5 块内引用全局变量:<__NSGlobalBlock__: 0x10fa74090> 全局区

  在MRC内的全局区在ARC还是全局区,在MRC的栈取都变成了堆区(ARC默认局部变量放在堆区)

 2,只要block引用外部局部变量,block就被放在堆区 <__NSMallocBlock__: 0x7fae1be08410> 堆区


七、block—变量传递

  1. block块内调用的是纯粹的局部变量时,是值传递

  2. block块内调用的是块外的静态局部变量、全局变量、__block修饰的块外部局部变量时,是指针传递


八、block的使用

1,block做方法的返回值:

     masonry的点语法加括号 链式语法,是用含有参数且返回值是当前对象的block做方法的返回值实现的

get方法可以通过点语法调用,有参数的方法不能通过点语法调用

    block在改方法调用时,调用了blodk

2,block做方法的参数:

     参数block在此方法实现时调用即可;


block补充:

九、block的修饰:

1.ARC

1.1copy修饰block,此block就会存在堆空间。则会对block的内部对象进行强引用,导致循环引用,内存无法释放。

解决方法:用__weak修饰在block块内用到的强指针类型的对象。

1.2 weak修饰block,此block会放在栈空间,引用外部强指针类型的对象,不会造成循环引用。

2.MRC

用copy修饰后,若果block块内使用了强指针类型的对象,则需要对此强指针类型的对象进行__block修饰,才不会造成循环引用