iOS block和代理的区别
block和代理是iOS开发中实现回调的两种方式,大多数情况下是用哪个都可以,主要看个人喜好。本文主要是对两者做一下对比。
1.block简介
在 iOS中, block一共分三种。
(1)全局静态 block,不会访问任何外部变量,执行完就销毁。
^{
NSLog(@"Hello World!");
}();
(2)保存在栈中的 block,当函数返回时会被销毁,和第一种的区别就是调用了外部变量。
[UIView animateWithDuration:3 animations:^{
self.view.backgroundColor = [UIColor redColor];
}];
(3)保存在堆中的 block,当引用计数为 0 时会被销毁。例如按钮的点击事件,一直存在,即使执行过,也不销毁,因为按钮还可能被点击,持有按钮的View被销毁,它才会被销毁。
#import <UIKit/UIKit.h>
typedef void(^ButtonClickBlcok)();
@interface TestView : UIView
@property (nonatomic, copy) ButtonClickBlcok buttonClickBlcok;
@end
#import "TestView.h"
@implementation TestView
- (IBAction)buttonClick:(id)sender {
if (self.buttonClickBlcok) {
self.buttonClickBlcok();
}
}
@end
2.block优点
block的代码可读性更好。因为应用block和实现block的地方在一起。代理的声明和实现就分开来了,在两个类中。代理使用起来也更麻烦,因为要声明协议、声明代理、遵守协议、实现协议里的方法。block不需要声明,也不需要遵守,只需要声明和实现就可以了。
block是一种轻量级的回调,可以直接访问上下文,由于block的代码是内联的,运行效率更高。block就是一个对象,实现了匿名函数的功能。所以我们可以把block当做一个成员变量、属性、参数使用,使用起来非常灵活。像用AFNetworking请求数据和GCD实现多线程,都使用了block回调。
3.block缺点
blcok的运行成本高。block出栈需要将使用的数据从栈内存拷贝到堆内存,当然对象的话就是引用计数加1,使用完或者block置nil后才销毁。delegate只是保存了一个对象指针(一定要用week修饰delegate,不然也会循环引用),直接回调,没有额外消耗。就像C的函数指针,只多做了一个查表动作。
block容易造成循环引用,而且不易察觉。因为为了blcok不被系统回收,所以我们都用copy关键字修饰,实行强引用。block对捕获的变量也都是强引用,所以就会造成循环引用。
#import "ViewController.h"
typedef void(^TestBlock)(void);
@interface ViewController ()
{
void (^_testCycleBlock)(void);
}
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
__weak ViewController *weakSelf = self;
_testCycleBlock = ^{
/**
//引发循环引用
NSLog(@"%@", self);
*/
//防止循环引用
NSLog(@"%@", weakSelf);
};
}
@end
4.如何使用
优先使用block。
如果回调函数很多,多余三个使用代理。
如果回调的很频繁,次数很多,像UITableview,每次初始化、滑动、点击都会回调,使用代理。
block和代理都各有优缺点,所以我们一定要理解区分使用场景,应用适合的回调方式。优化APP的性能,提高流畅性,从点滴做起。
iOS block和代理的区别的更多相关文章
- ios block和函数的区别
block是封装了一段代码的OC对象,可以被设为Property, 在调用block的地方block都会被替换成相应的代码,相当于内联函数. 函数可以使代码更加整洁易读,使用block会使代码可读性变 ...
- iOS开发——OC篇&消息传递机制(KVO/NOtification/Block/代理/Target-Action)
iOS开发中消息传递机制(KVO/NOtification/Block/代理/Target-Action) 今晚看到了一篇好的文章,所以就搬过来了,方便自己以后学习 虽然这一期的主题是关于Fou ...
- ios Block详细用法
ios Block详细用法 ios4.0系统已开始支持block,在编程过程中,blocks被Obj-C看成是对象,它封装了一段代码,这段代码可以在任何时候执行.Blocks可以作为函数参数或者函数的 ...
- iOS block从零开始
iOS block从零开始 在iOS4.0之后,block横空出世,它本身封装了一段代码并将这段代码当做变量,通过block()的方式进行回调. block的结构 先来一段简单的代码看看: void ...
- iOS Block(一)
Block使用总结: 1.格式: ReturnType (^ BlockName)(参数…); //例: int (^ BFunc) (int a, int b); 2.block赋值: block名 ...
- IOS学习3——代理
本文转载自:你真的了解iOS代理设计模式吗? 在项目中我们经常会用到代理的设计模式,这是iOS中一种消息传递的方式,也可以通过这种方式来传递一些参数.这篇文章会涵盖代理的使用技巧和原理,以及代理的内存 ...
- iOS block 机制
本文要将block的以下机制,并配合具体代码详细描述: block 与 外部变量 block 的存储域:栈块.堆块.全局块 定义 块与函数类似,只不过是直接定义在另一个函数里,和定义它的那个函数共享同 ...
- iOS Block的本质(四)
iOS Block的本质(四) 上一篇文章iOS Block的本质(三)中已经介绍过block变量的捕获,本文继续探寻block的本质. 1. block内修改变量的值 int main(int ar ...
- iOS Block的本质(二)
iOS Block的本质(二) 1. 介绍引入block本质 通过上一篇文章Block的本质(一)已经基本对block的底层结构有了基本的认识,block的底层就是__main_block_impl_ ...
随机推荐
- [补档][Hnoi2013]游走
[Hnoi2013]游走 题目 一个无向连通图,顶点从1编号到N,边从1编号到M. 小Z在该图上进行随机游走,初始时小Z在1号顶点,每一步小Z以相等的概率随机选 择当前顶点的某条边,沿着这条边走到下一 ...
- C++ STL Binary search详解
一.解释 以前遇到二分的题目都是手动实现二分,不得不说错误比较多,关于返回值,关于区间的左闭右开等很容易出错,最近做题发现直接使用STL中的二分函数方便快捷还不会出错,不过对于没有接触过的同学,二分函 ...
- 木棍分割[HAOI2008]
题目描述 有n根木棍, 第i根木棍的长度为Li,n根木棍依次连结了一起, 总共有n-1个连接处. 现在允许你最多砍断m个连接处, 砍完后n根木棍被分成了很多段,要求满足总长度最大的一段长度最小, 并且 ...
- little bird
LITTLE BIRD Bzoj 3831 相对而言是一道比较简单的DP,不过它需要用单调队列优化.首先是朴素O(n2), if(d[j]>f[i]) f[i]=min(f[i],f[j]); ...
- python学习===如何理解python中的return
首先要了解,函数是什么?书上可能会说函数是完成功能的模块之类的话.其实说白了,函数就是个你招来的工人.你给他一些材料,告诉他怎么用这些材料拼装,然后他负责把拼装好的成品交给你.材料就是函数的参数,成品 ...
- 6个Linux chkconfig命令实例 - 增加,删除,查看和修改services的自动启动选项
注意:service的安装目录在/etc/rc.d/init.d下,/etc/init.d 是/etc/rc.d/init.d的链接. chkconfig命令用来安装,查看或修改 services随系 ...
- Unity3D --对撞机/碰撞器 介绍
碰撞器一般都用作触发器而用,刚体一般用作真实碰撞. 静态对撞机:一个对象有对撞机组件,没有刚体组件. 这种情况在场景中的静态物体应用较多,比如墙体,房屋等静止不动的物体. 物理引擎假设静态对撞机是不会 ...
- js的dom操作和函数
dom是稳当对象模型,文档指标签文档,对象指文档中每个元素,模型指抽象画的东西. js常用函数 日期时间函数(需要用变量调用):var b = new Date(); //获取当前时间b.getTim ...
- Gate One
运维堡垒机介绍: 运维堡垒机的理念起源于跳板机.2000年左右,高端行业用户为了对运维人员的远程登录进行集中管理,会在机房里部署跳板机.跳板机就是一台服务器,维护人员在维护过程中,首先要统一登录到这台 ...
- imshow显示超大图像
在matlab做图像处理时,有些图片比较大,或者自己的显示器比较小,又要求查看完整的图片怎么办呢? 如果使用imshow直接显示,则显然没法达到要求.最好的办法还是滚动条: hFig = figure ...