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_ ...
随机推荐
- mysql中varchar和char区别(思维导图整理)
由于mysql一直是我的弱项(其实各方面我都是很弱的),所以最近在看msyql,正好看到varchar和char区别,所以整理一下,便于以后遗忘. 0.0图片已经说明一切,但是系统说我字数不够,我真能 ...
- JavaScript 排序算法(JavaScript sorting algorithms)
JavaScrip 排序算法(JavaScript Sorting Algorithms) 基础构造函数 以下几种排序算法做为方法放在构造函数里. function ArrayList () { va ...
- HDU 1159 Common Subsequence:LCS(最长公共子序列)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1159 题意: 求最长公共子序列. 题解: (LCS模板题) 表示状态: dp[i][j] = max ...
- oracle启动 init.ora spfile pfile[转]
昨天晚上快下班的时候,公司数据库突然堵住了,一个buf表中累计了20多W的数据提取不出来,改了程序,效果不明显.因为之前有一次也重启过oracle,所以这次还是想把oracle重启一下,因为那些数据都 ...
- C# 调用 C++ DLL方法
在C# 中,可以通过 DllImport 调用C++ 的非托管DLL程序. VS2010中C#调用C++的DLL示例: 一.新建C++ DLL程序 1.新建 C++ Win32项目,类型为DLL. 生 ...
- 常见C/C++笔试、面试题(二)
我自己总结过一些常见的C++面试题,那个是基于一个同学的腾讯面经所问问题,再加上知识点扩展进行了总结,这个是网上之前就有的版本,比较基础,有些题目总结一下,不能忘了基础: 1.求下面函数的返回值( 微 ...
- UML类图及依赖,泛化,关联,聚合,组合,实现
UML图中类之间的关系:依赖,泛化,关联,聚合,组合,实现 类与类图 1) 类(Class)封装了数据和行为,是面向对象的重要组成部分,它是具有相同属性.操作.关系的对象集合的总称. 2) 在系统中, ...
- ACM做题过程中的一些小技巧
1.一般用C语言节约空间,要用C++库函数或STL时才用C++; cout.cin和printf.scanf最好不要混用. 2.有时候int型不够用,可以用long long或__int64型(两个下 ...
- JPA的学习
JPA 1.实体注解 @Entity主键注解 @Id 主键策略@GeneratedValue(strategy=GenerationType.AUTO[IDENTITY,SEQUENCE,TAB ...
- [js高手之路]使用原型对象(prototype)需要注意的地方
我们先来一个简单的构造函数+原型对象的小程序 function CreateObj( uName, uAge ) { this.userName = uName; this.userAge = uAg ...