Block 的使用
2016-12-07 14:18
232 查看
block :代码块,用过代理的同学可能都知道,其实block就相当于一个代理,但是给代理又略有不同。
下面我就详细的介绍一下block,不足之处欢迎指正。
上面这段代码就是一个block语句。
在这个条代码中:返回值类型为int,"^"这个符号表示这是一个block。
”^“符号将myBlock声明为一个块对象,myBlock为对象名。
有两个参数,参数类型是int。
”=“后面,是定义block对象的语法结构,给myBlock变量赋值。
参数类型是int类型,参数名是a,b。{}里面是对象的主体部分。
定义一个有参数,返回值类型为NSString类型的block:
定义一个无参数,无返回值类型的block
上面这三个block都是写在 viewDidLoad 方法里面的。
在类中,定义一个block变量,就像定义一个函数;block可以定义在方法内部,也可以定义在方法外部(定义在方法外部,就是文件级别的全局变量);只有调用block时候,才会执行其{}体内的代码。
block内部可以访问外部的变量;默认情况下,block内部不能修改外部的局部变量(全局变量可以);给局部变量加上__block关键字,则这个局部变量可以在block内部得到修改。
定义在方法外部:无返回值,有参数的block
定义在方法外部:有返回值,有参数的block
使用block做property,实现两个页面之间的传值:
B.viewController .h 文件中内容
A.viewController 跳转B.viewController响应事件中的内容
B.viewController 触发事件方法给A.viewController传值的内容
B.viewController .h 文件中内容还可以这样写,给myBlock起一个别名
__weak typeof(self) weakSelf = self;
什么时候在block里面用self,不需要使用weakSelf ?
/**
* 1.当block
本身不被self持有,而被别的对象持有,同时不产生循环引用的时候,就不需要使用weak self了。
* 2.UIView 的某个负责动画的对象持有了block,block
持有了self,因为self不持有block,所以就没有了循环引用产生,因此就不需要使用weak
self了。
* 3.当动画结束时,UIView会结束持有这个block,如果没有别的对象持有block的话,block对象就会释放掉,而block会释放掉对于self的持有。整个内存引用关系被解除。
*
*/
[UIView
animateWithDuration:1
animations:^{
} completion:^(BOOL finished) {
}];
为什么block里面还需要写一个strong self,如果不写会怎样?
/**
* 1.在block中先写一个strong self,其实是为了避免在block
的执行过程中,突然出现self被释放的尴尬情况。通常情况下,如果不这么做的话,还是很容易出现一些奇怪的逻辑,甚至闪退。
* 2.如果没有strong self
的那行代码,那么后面的每一行代码执行时,self
都有可能被释放掉了,这样很可能造成逻辑异常。甚至是崩溃。
*
*/
__weak typeof(self) weakSelf =
self;
[self fun:^(NSString *str,
UIColor *col) {
__strong
typeof(weakSelf) strongSelf = weakSelf;
if (strongSelf) {
}
}];
需要不使用weak self的场景是:需要构造一个循环引用,以保证引用双方都存在。比如有一个后台的任务,希望任务执行完后,通知另外一个实例。
/**
* 例如:
每一个网络请求API会持有回调的block,回调的block会持有self,而如果self也持有网络请求API的话,我们就构造了一个循环引用。虽然我们构造出了循环引用,但是因为在网络请求结束时,网络请求API会主动释放对block的持有,因此整个循环链条被解开,循环引用就被打破了,所以不会有内存泄漏问题。
*
* 解决循环引用有两个方法:
* 1.事前避免,我们在会产生循环引用的地方使用weak弱引用,以避免产生循环引用。
* 2.事后补救,我们明确知道会产生循环引用,但是我们在合理的位置主动断开环中的一个引用,使得对象得以回收。
*
*/
参考博客地址:
https://my.oschina.net/leejan97/blog/268536 http://blog.csdn.net/totogo2010/article/details/7839061
唐巧的技术博客,微信号:iosDevTips
下面我就详细的介绍一下block,不足之处欢迎指正。
上面这段代码就是一个block语句。
在这个条代码中:返回值类型为int,"^"这个符号表示这是一个block。
”^“符号将myBlock声明为一个块对象,myBlock为对象名。
有两个参数,参数类型是int。
”=“后面,是定义block对象的语法结构,给myBlock变量赋值。
参数类型是int类型,参数名是a,b。{}里面是对象的主体部分。
定义一个有参数,返回值类型为NSString类型的block:
定义一个无参数,无返回值类型的block
上面这三个block都是写在 viewDidLoad 方法里面的。
在类中,定义一个block变量,就像定义一个函数;block可以定义在方法内部,也可以定义在方法外部(定义在方法外部,就是文件级别的全局变量);只有调用block时候,才会执行其{}体内的代码。
block内部可以访问外部的变量;默认情况下,block内部不能修改外部的局部变量(全局变量可以);给局部变量加上__block关键字,则这个局部变量可以在block内部得到修改。
定义在方法外部:无返回值,有参数的block
定义在方法外部:有返回值,有参数的block
使用block做property,实现两个页面之间的传值:
B.viewController .h 文件中内容
A.viewController 跳转B.viewController响应事件中的内容
B.viewController 触发事件方法给A.viewController传值的内容
B.viewController .h 文件中内容还可以这样写,给myBlock起一个别名
__weak typeof(self) weakSelf = self;
什么时候在block里面用self,不需要使用weakSelf ?
/**
* 1.当block
本身不被self持有,而被别的对象持有,同时不产生循环引用的时候,就不需要使用weak self了。
* 2.UIView 的某个负责动画的对象持有了block,block
持有了self,因为self不持有block,所以就没有了循环引用产生,因此就不需要使用weak
self了。
* 3.当动画结束时,UIView会结束持有这个block,如果没有别的对象持有block的话,block对象就会释放掉,而block会释放掉对于self的持有。整个内存引用关系被解除。
*
*/
[UIView
animateWithDuration:1
animations:^{
} completion:^(BOOL finished) {
}];
为什么block里面还需要写一个strong self,如果不写会怎样?
/**
* 1.在block中先写一个strong self,其实是为了避免在block
的执行过程中,突然出现self被释放的尴尬情况。通常情况下,如果不这么做的话,还是很容易出现一些奇怪的逻辑,甚至闪退。
* 2.如果没有strong self
的那行代码,那么后面的每一行代码执行时,self
都有可能被释放掉了,这样很可能造成逻辑异常。甚至是崩溃。
*
*/
__weak typeof(self) weakSelf =
self;
[self fun:^(NSString *str,
UIColor *col) {
__strong
typeof(weakSelf) strongSelf = weakSelf;
if (strongSelf) {
}
}];
需要不使用weak self的场景是:需要构造一个循环引用,以保证引用双方都存在。比如有一个后台的任务,希望任务执行完后,通知另外一个实例。
/**
* 例如:
每一个网络请求API会持有回调的block,回调的block会持有self,而如果self也持有网络请求API的话,我们就构造了一个循环引用。虽然我们构造出了循环引用,但是因为在网络请求结束时,网络请求API会主动释放对block的持有,因此整个循环链条被解开,循环引用就被打破了,所以不会有内存泄漏问题。
*
* 解决循环引用有两个方法:
* 1.事前避免,我们在会产生循环引用的地方使用weak弱引用,以避免产生循环引用。
* 2.事后补救,我们明确知道会产生循环引用,但是我们在合理的位置主动断开环中的一个引用,使得对象得以回收。
*
*/
参考博客地址:
https://my.oschina.net/leejan97/blog/268536 http://blog.csdn.net/totogo2010/article/details/7839061
唐巧的技术博客,微信号:iosDevTips
相关文章推荐
- Ruby中Block和迭代器的使用讲解
- Ruby中使用Block、Proc、lambda实现闭包
- Ruby中的block、proc、lambda区别总结
- Ruby中的block代码块学习教程
- 如何消除inline-block属性带来的标签间间隙
- iOS中Block的回调使用和解析详解
- 全面解析Objective-C中的block代码块的使用
- iOS利用Block逆向传值的方式详解
- iOS通过block在两个页面间传值的方法
- block 实现原理详解(一)
- __block的作用和功能
- Block的循环引用
- iOS页面传值总结
- block作为属性,作为参数,作为返回值各种情况演示
- 为对象添加一个释放时触发的block
- Block内存管理实例分析
- Swift与OC真正去理解Block解决循环引用的技巧
- iOS 开发中你是否遇到这些经验问题(二)
- ios高效开发二--ARC跟block那点事