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的性能,提高流畅性,从点滴做起。

最新文章

  1. Javascript对象
  2. PHP——使用header()函数下载文件
  3. notifyDataSetInvalidated和notifyDataSetChanged有什么区别
  4. synchronized同步块和volatile同步变量
  5. BZOJ4002 [JLOI2015]有意义的字符串
  6. Processon 一款基于HTML5的在线作图工具
  7. HDU 5384 Danganronpa (Trie树)
  8. JS 获取select(多选下拉)中所选值的示例代码
  9. 【 NOIP2015 DAY1 T2 信息传递】带权并查集
  10. PC-用Windows XP自带的组策略加固操作系统
  11. c语言学习之基础知识点介绍(十三):枚举的介绍和使用
  12. ASP.NET MVC5 easyui 之 treegrid 初用记录
  13. absolut绝对定位的非绝对定位用法
  14. oracle审计
  15. Mysql常用命令行大全(转)
  16. [DP][NOIP2015]子串
  17. 6 基于Servlet 的分页
  18. Ionic1.x项目中的Installing npm packages问题
  19. c# 类的知识
  20. 关于NLP和深度学习,准备好好看看这个github,还有这篇介绍

热门文章

  1. Codeforces 828B Black Square(简单题)
  2. Ubuntu下安装codeblocks
  3. Android 原生 Intent 分享支持的那些事
  4. HTML的基本结构与标签的初步了解
  5. MySQL编程基础
  6. Linux的nginx环境的vue 部署
  7. VMvare 虚拟网卡vmnet1 and vmnet8
  8. 立即表达式的多种写法与注意点以及in操作符的作用
  9. ReactiveCocoa应用篇(二)
  10. 在Android中使用枚举注解而不是枚举