Block的使用及循环引用的解决
Block是一个很好用的东西,这篇文章主要来介绍:1.什么是Block?2.Block的使用?3.Block的循环引用问题及解决.
1.什么是Block?
说这个问题之前,我先来说一下闭包(Closure)。闭包就是一个函数,或者一个指向函数的指针,加上这个函数执行的非局部变量。说的通俗一点,就是闭包允许一个函数访问声明该函数运行上下文中的变量,甚至可以访问不同运行上文中的变量。
Block实际上就是OC语言对闭包的实现。
下面声明一个Block:
int (^Sum)(int, int);
首先,第一个int也就是该Block的返回值类型,也可以是其他的返回值类型,或者无返回值。“^”是Block的标识。第二以及第三个int,则是Block的参数类型,当然也可以无参数。
下面的代码则是定义了一个Block,当执行Line5代码时,会输出“nihao”,也就是给Block传入的参数。
void (^printBlock)(NSString *) = ^(NSString *str) {
NSLog(@"%@", str);
};
printBlock(@"nihao");
下面借鉴一张网上流传的图片总结一下Block的结构:

需要说明的是,Block能够直接修改和访问全局变量,但是只能访问局部变量,如果想要在Block中修改局部变量,使用 __block 修饰即可。关于Block的基本介绍就是这么多了。有需要的tx可以留言,再做适当的更新。下面简单说说Block的使用。
2.Block的使用
2.1 使用Block在不同的页面进行传值
页面传值有很多方式,比如:属性、单例、通知、代理,Block等。这里单说使用Block传值,其他几种以后再做补充。
使用Block传值也有两种方式:Block属性和使用Block作为参数的方法。
2.1.1 使用Block属性传值
下面演示的是从B页面(后一个页面)传值到A页面(前一个页面)。
首先在B页面中声明一个Block,通常为了使代码简洁,我一般会对Block进行重定义:
typedef void (^PassVal)(NSString *text);
接着,在B中声明一个Block属性:
@property (nonatomic, copy) PassVal passVal;
这里需要注意下,我使用了copy,实际上在ARC环境下,使用copy和strong都是可行的。我这里只是为了表明,使用Block时,实际上是把Block从栈区拷贝到了堆区。
下面继续。我这里选择在B页面即将消失时,将值传出:
- (void)viewWillDisappear:(BOOL)animated {
if (self.passVal) {
self.passVal(@"");
}
}
我们可以看一下前面声明的Block是一个有参(string类型),无返回值。这里我给Block的参数是@"123456798"。通过上面的处理,B页面的操作已经完成了。下面进行A页面的操作:
- (void)btnNextAction:(UIButton *)btnNext {
BViewController *BVC = [[BViewController alloc] init];
BVC.passVal = ^(NSString *text) {
NSLog(@"%@",text);
};
[self.navigationController pushViewController:BVC animated:YES];
}
上面的代码演示了,在点击按钮即将push到B页面时,来实现Block。这样就可以在A页面中得到B页面的值,也就是text值。到此,Block属性传值结束。
2.1.2 使用带有Block参数的方法传值
这种方式和属性传值类似,下面做简单的示例:
typedef void (^PassVal)(NSString *text); @interface SecondViewController : UIViewController @property (nonatomic, copy) PassVal passVal; - (void)returnText:(PassVal)block; @end
首先在第二个页面同样需要声明Block属性,同时在第二个页面声明一个方法,方法的参数即是属性同样类型的Block。接着实现下面的方法:
- (void)viewWillDisappear:(BOOL)animated {
if (self.passVal) {
self.passVal(@"");
}
}
- (void)returnText:(PassVal)block {
self.passVal = block;
}
首先要做的还是先给Block的参数赋值,接着要实现声明的方法。接下来去第一个页面操作:
- (void)btnNextAction:(UIButton *)btnNext {
SecondViewController *secCtr = [[SecondViewController alloc] init];
[secCtr returnText:^(NSString *text) {
NSLog(@"%@",text);
}];
[self.navigationController pushViewController:secCtr animated:YES];
}
这样也可以实现传值。
使用方法传值,猛一看觉得挺麻烦,但是实际上,使用方法调用的方式是很容易理解的。
传值只是Block的简单应用,总体来说,Block和代理的使用时很类似的,可以互相参考着学习。
3.Block的循环引用问题及解决.
首先我们需要明确的是,一个对象的Block属性是使用copy来修饰,当Block被copy时,会对block中用到的对象产生强引用(ARC)或者引用计数加一(MRC)。当我们使用Block时,如果Block方法又引用了对象,如使用 self. 来引用对象的属性,这就会造成循环引用。其实如果产生了循环引用我们也不需要很担心,因为编译器会自动提醒,只需要在提醒的时候进行处理就可以了.一般在ARC下可以这么处理(仅作为示例用法):
__weak typeof(self)weakSelf = self;
[self.tableView addHeaderWithCallback:^{
weakSelf.isDown = YES;
weakSelf.page = ;
[weakSelf requestData];
}];
也就是说,把需要使用self的地方换成weakSelf即可.如果是MRC,只需要把上面代码的第一行更换为:
__block typeof(self)weakSelf = self;
以上仅作为各位使用的参考,如果有不到位的地方,欢迎各位留言指出,大家一起交流.
Block的使用及循环引用的解决的更多相关文章
- block(六)循环引用-b
在ARC与非ARC环境下对block使用不当都会引起循环引用问题,一般表现为,某个类将block作为自己的属性变量,然后该类在block的方法体里面又使用了该类本身,简单说就是self.theBloc ...
- C#项目间循环引用的解决办法,有图有真相
C#项目间循环引用的解决办法,有图有真相 程序间的互相调用接口,c#禁止互相引用,海宏软件,20160315 /// c#禁止互相引用,如果项目[订单]中有一个orderEdit单元,要在项目[进销存 ...
- IOS block 循环引用的解决
在介绍block循环引用前我们先了解一下typeof. typeof是什么??? typeof 是一个一元运算,放在一个运算数之前,运算数可以是任意类型. 它返回值是一个字符串,该字符串说明运算数的类 ...
- block中如何避免循环引用
使用 weak–strong dance 技术 block 可以直接引用 self,但是要非常小心地在 block 中引用 self.因为在 block 引用 self,可能会导致循环引用.如下例所示 ...
- 关于Block的copy和循环引用的问题
http://blog.csdn.net/felix9/article/details/9619313 在实际开发中,发现使用Block有着比delegate和notification更简洁的优势.于 ...
- Block的copy和循环引用的问题
在实际开发中,发现使用Block有着比delegate和notification更简洁的优势.于是在目前的项目中大量的使用block. 在我的头文件我是这样声明使用block的. 我将block声明为 ...
- block的用法和循环引用
一.block在OC中的用法可以分为大概一下几种. 1>用于成员属性,保存一段代码,可以替代代理传值. 比如说,创建一个ViewController控制器,点击屏幕就跳转到ModalViewCo ...
- iOS - Block产生Memory Leaks循环引用导致的内存泄漏以及解决方案
在ARC(自动引用技术)前,Objective-c都是手动来分配释放 释放 计数内存,其过程非常复杂. ARC技术推出后,貌似世界和平了很多,但是其实ARC并不等同于Java或者C#中的垃圾回收,AR ...
- block使用小结、在arc中使用block、如何防止循环引用
引言 使用block已经有一段时间了,感觉自己了解的还行,但是几天前看到CocoaChina上一个关于block的小测试主题: [小测试]你真的知道blocks在Objective-C中是怎么工作的吗 ...
随机推荐
- fusioncharts图例(legend)属性
图例用来在多系列图和混合图中将图形和对应的系列名称联系起来. 从v3.2开始,每个系列的名称前面会展示对应的icon图标,这些图标具有交互作用,用户可以通过点击这些图标来显示或者隐藏对应的数 ...
- Java 时间日期系列目录
下面是Java的时间和日期相关文章目录: 01. Java Calendar,Date,DateFormat,TimeZone,Locale等时间相关内容的认知和使用(1) Calendar 02. ...
- [IR] Probabilistic Model
If user has told us some relevant and some irrelevant documents, then we can proceed to build a prob ...
- 4、总结:基于Oracle Logminer数据同步
最近开发Oracle数据同步功能,做了些调研和验证,这个工作过去有段时间,怕时间长了忘记,故用博客共享出来.在这系列中共写了三篇文章,第一篇是写LogMiner配置及使用,第二篇是测试了LogMine ...
- 求1+2+3+...+n
求1+2+3+...+n,要求不能使用乘除法.for.while.if.else.switch.case等关键字及条件判断语句(A?B:C). 卧槽,剑指Offer竟然有这样的题... public ...
- 3 Servlet监听器
作者:禅楼望月(http://www.cnblogs.com/yaoyinglong) 1. ServletConfig和ServletContext 1.1 ServletConfig和Servle ...
- Spring基础——一个简单的例子
一.学习版本 spring-framework-4.0.0 二.导入 jar 包: 三.在类路径下创建 Spring Config 文件:ApplicationContext.xml <?xml ...
- ADO.NET 基础
*程序要和数据库交互要通过ADO.NET进行,通过ADO.NET就能在程序中执行SQL了,ADO.NET中提供了对各种不同数据库的统一操作接口. 1.连接SQLServer 连接字符串,程序通过链接字 ...
- Brute Force --- UVA 10167: Birthday Cake
Problem G. Birthday Cake Problem's Link:http://uva.onlinejudge.org/index.php?option=com_onlinejudg ...
- AEAI ESB V3.5.4开源发布,应用集成平台
AEAI ESB 应用集成平台为数通畅联的核心产品,本着分享传递的理念,数通畅联将ESB管理控制台项目开源,目的在于满足客户与伙伴的OEM需求,以及为广大IT爱好者的集成工具提供多一种选择,多一种便利 ...