一、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修饰,才不会造成循环引用