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的使用及循环引用的解决的更多相关文章

  1. block(六)循环引用-b

    在ARC与非ARC环境下对block使用不当都会引起循环引用问题,一般表现为,某个类将block作为自己的属性变量,然后该类在block的方法体里面又使用了该类本身,简单说就是self.theBloc ...

  2. C#项目间循环引用的解决办法,有图有真相

    C#项目间循环引用的解决办法,有图有真相 程序间的互相调用接口,c#禁止互相引用,海宏软件,20160315 /// c#禁止互相引用,如果项目[订单]中有一个orderEdit单元,要在项目[进销存 ...

  3. IOS block 循环引用的解决

    在介绍block循环引用前我们先了解一下typeof. typeof是什么??? typeof 是一个一元运算,放在一个运算数之前,运算数可以是任意类型. 它返回值是一个字符串,该字符串说明运算数的类 ...

  4. block中如何避免循环引用

    使用 weak–strong dance 技术 block 可以直接引用 self,但是要非常小心地在 block 中引用 self.因为在 block 引用 self,可能会导致循环引用.如下例所示 ...

  5. 关于Block的copy和循环引用的问题

    http://blog.csdn.net/felix9/article/details/9619313 在实际开发中,发现使用Block有着比delegate和notification更简洁的优势.于 ...

  6. Block的copy和循环引用的问题

    在实际开发中,发现使用Block有着比delegate和notification更简洁的优势.于是在目前的项目中大量的使用block. 在我的头文件我是这样声明使用block的. 我将block声明为 ...

  7. block的用法和循环引用

    一.block在OC中的用法可以分为大概一下几种. 1>用于成员属性,保存一段代码,可以替代代理传值. 比如说,创建一个ViewController控制器,点击屏幕就跳转到ModalViewCo ...

  8. iOS - Block产生Memory Leaks循环引用导致的内存泄漏以及解决方案

    在ARC(自动引用技术)前,Objective-c都是手动来分配释放 释放 计数内存,其过程非常复杂. ARC技术推出后,貌似世界和平了很多,但是其实ARC并不等同于Java或者C#中的垃圾回收,AR ...

  9. block使用小结、在arc中使用block、如何防止循环引用

    引言 使用block已经有一段时间了,感觉自己了解的还行,但是几天前看到CocoaChina上一个关于block的小测试主题: [小测试]你真的知道blocks在Objective-C中是怎么工作的吗 ...

随机推荐

  1. DDD:订单管理 之 如何组织代码

    背景 系统开发最难的是职责的合理分配,或者叫:“如何合理的组织代码”,今天说一个关于这方面问题的示例,希望大家多批评. 示例背景 参考数据字典 需求 OrderCode必须唯一. Total = Su ...

  2. 15套帮助你展示 App 设计的透视屏幕原型素材

    Dribbble 和 Behance 是最好两个展示你的设计作品的地方.现在流行使用透视屏幕来展示应用程序设计效果,尤其是在 Dribbble 上面,有众多高品质的免费资源和设计素材. 这篇文章汇集了 ...

  3. SSL握手步骤【收藏】

    http://www.codeweblog.com/ssl-handshake-process-of-interaction-and/ SSL to send a message in the fol ...

  4. ASP.NET MVC 使用 IOC框架 AutoFac 自动释放数据库资源

    每次使用using或者dispose来释放资源会比较麻烦,作为一个会偷懒的程序员来说当然不能接受了. 一.引用 autofac.dll和autofac.integration.mvc.dll 二.打开 ...

  5. 0422 发现( 数学口袋精灵)bug

    团队博客地址: 甘佳萍:http://www.cnblogs.com/gjpg/ 李鹏飞:http://www.cnblogs.com/l549023320/ 赵创佳:http://www.cnblo ...

  6. 【Win10】让 AppBarButton 支持更复杂的 Icon 内容

    最近有一个需求,需要制作这么一个 AppBarButton: 这个 AppBarButton 的 Icon 是一个评论框图标里面再显示评论数(大于 99 条则显示 99+).其中评论数是通过数据绑定得 ...

  7. Web控件文本框Reset的功能

    在前一篇中<怎样实现Web控件文本框Reset的功能>http://www.cnblogs.com/insus/p/4120889.html Insus.NET只实现了文本框的功能.单个或 ...

  8. 【原创】C#通用权限管理-程序安全检查,这些你一定要考虑到位

    接触通用权限已经一年,现在使用已经很熟练,分享通用权限管理下面的一些好的开发思想. 安全漏洞对于一个小项目来说,可能不是特别的重视,对于一个大项目来说,这是特别重要需要注意的,特别是在项目开发中的就要 ...

  9. Maven创建webapp(二)

    这一节将记录在myeclipse下用maven创建一个简单的webapp项目 web开发maven仓库自动添加组件,故需要需要保持网络的通畅. 打开myeclipse  -->  File  - ...

  10. Java的集合框架

    01.为什么要使用集合框架? 解析:如果并不知道程序运行时会需要多少对象,或者需要更复杂方式存储对象,那么可以使用Java集合框架. 如果启用集合的删除方法,那么集合中所有元素的索引会自动维护. 集合 ...