block简介
block是一种基本的数据类型,用于存储代码块,在需要的时候调用,与函数的区别是函数保存的代码,一旦调用立即执行,block可以在需要时候执行.
形式如下:
返回值 (^block名称)(参数列表) = ^(参数列表) {
代码块
}
通过返回值和参数的组合有四种形式:
有参数有返回值的block
无参数有返回值的block
没有返回值有参数的block
没有返回值没有参数的block
block的typedef使用
和其他的其别名类似,只是block的类型是: 返回值 (^)()
如下:
DemoBlock就是返回值是int 有两个参数为int类型的block, 返回值和参数是这种类型都是DemoBlock.
block的使用
block作为方法的参数
block作为作为类的属性
block作为属性应该用copy修饰
1.当用weak、assign修饰block属性时,block访问外部变量,此时block的类型是栈block. 保存在栈中的block, 当block所在函数\\方法返回\\结束, 该block就会被销毁. 在其他方法内部调用访问该block, 就会引发野指针错误.
2.当用copy、strong修饰block属性时, block访问外部变量, 此时block的类型是堆block. 保存在堆中的block, 当引用计数器为0时被销毁, 该类型block是由栈类型的block从栈中复制到堆中形成的, 因此可以在其他方法内部调用该block. 在ARC下,strong和copy都可以用来修饰block, 但是建议修饰block属性使用copy.
这两种是block的常用使用方式,具体在下面代码中展示.
block传值与回调
block在传值和回调方面和代理的作用相同,block使用简洁方便一点,
在网络异步回调时一般都使用block回调,下面使用两个小案例进行演示.
第一个: 反向传值,将一个参数从一个控制器传到另一个控制器.
将输入的文本从B控制器点击点击按钮传到A控制器
代码实现部分
B控制器添加一个block属性
添加按钮,在点击的时候将文本框内的字符串传到A控制器并返回到A控制器
接收传过来的数据并显示到label上
第二个:block回调,通过一个自定义工具类回调返回数据
点击存储文本框中内容,保存到沙盒,
再点击通过自定义工具类取出沙盒内容,回调返回数据
控制器回调方法
自定义工具类类方法
block传值与回调Demo的源码
源码地址 https://git.oschina.net/weidream/MyCode.git
block的使用注意事项
1.block内部不能直接修改局部变量
block内部可以访问外部的变量, 默认是将其拷贝到其数据结构中来实现访问的, 属性是只读的. block内部不能修改外面的局部变量.
如果要修改需要对要修改的局部变量用__block 修饰, 这样局部变量就可以在block内部修改了,block是复制其引用地址来实现访问的
2.当block里面的出现self,造成的循环引用
循环引用就是当self 拥有一个block的时候, 在block中又调用self的方法. 形成了你中有我, 我中有你, 造成谁都无法将谁释放, 从而发生内存泄漏.
解决方法:
__weak typeof (self) weakSelf = self;
定义一个weakSelf变量并加上__weak修饰符, 在Block代码块中, 所有需要self的地方都用weakSelf来替代。这样就不会增加引用计数, 所以Block持有self对象也就不会造成循环引用,从而造成内存泄漏.