闭包, 代理和通知的区别?


1. 闭包: 就是block, 在swift中叫做闭包

block是iOS4.0+ 和Mac OS X10.6+ 引进的C语言的扩展, 用来实现匿名函数的特征

blocks语法块代码以闭包的形式将各种内容进行传递, 可以是代码, 可以是数组, 什么都可以

block是一个数据类型, 存放一段代码, 编译的时候不会执行, 只有用到的时候才会去执行里面的代码. 声明的时候使用 copy 是因为要从栈区拷贝到堆区, 在栈区会受到作用域的限制, 超出所在的函数就会被销毁, 就没办法进行传值回调等一系列操作了. 

闭包是能够读取其他函数内部变量的函数, 在一段连续请求代码中可以清晰的看到调用参数 (比如发送请求) 和响应结果. 所有采用block能够抽取出很多公共函数, 大大提高了代码的可读性, 可维护性, 封装性

> 最常见的使用场景: 数据请求回调

> 使用注意: 注意防止 循环引用

ARC下使用__weak来修饰, MRC下使用__block来修饰(如果一个变量在 block 外部创建, 需要在 block 内部修改, 那么需要使用 block 修饰这个变量, block 可以再 ARC 和 MRC 情况下使用, 可以修饰对象和基本数据类型, weak 只能在 ARC 下使用, 只能修饰对象, 不能修饰基本数据类型)


2. 代理: 一对一, 对用一个协议, 一个对象只能设置一个代理delegate

> 使用步骤:

1) 委托方声明协议定义代理方法

2) 在委托方判断代理方有没有实现代理方法

3) 代理方遵守协议设置代理事项代理方法

> 注意:

1) 单利对象不能用代理

2) 代理执行协议方法时要使用responds ToSelector检查代理是否符合协议(检查对象能否响应指定消息), 避免代理回调时因为没有实现代理方法而造成的崩溃

> 使用场景: 比如方法较多时可以选择delegate进行解耦


3. 通知: 一对一, 一对多传值

> 使用步骤: 

1) 发送通知

2) 监听通知

3) 移除通知

4) 实现通知的监听方法

> 使用场景: 比如相隔多层的两个控制器之间跳转

> 注意: 

1) 一旦接受消息的对象多了, 就难以控制了, 可能有你不希望的对象接受了消息并做了处理

2) 创建了监听者, 要在dealloc里面移除, swift里面在deinit中移除


> 下面我们来做详细的对比

从效率来说delegate和block都要比NSNOtification高, NSNOtification是重量级的, 开发中根据实际情况做具体选择

1) delegate和block一般都是一对一的通信

2) delegate需要定义协议方法,实现协议方法, 并且要建立代理关系才可以通信, block更加简洁, 但通信时间较多的话,建议使用delegate

3) delegate运行成本低, block成本高

    block出栈要把使用的数据从栈内存copy到堆内存, 当然对象的话就是加计数, 使用完或者block置nil后才消除; delegate只是保存了一个对象指针, 直接回调, 没有额外消耗

4) delegate注重过程信息的传输: 比如发起一个网络请求, 可能想要知道此时请求是否已经开始, 是否收到了数据, 数据是否已经接收完成, 数据接收失败 

    block注重结果传输: 比如网络请求数据, 只知道成功或者失败就可以了, 并不需要知道进行了多少或者额外的一些信息

5) block更清晰. 比如一个viewController中有多个事件, delegate需要对每个事件进行判断识别来源. 而block可以在创建事件的时候区分开来. 这也是为什么苹果官方建议更多的使用block而不是delegate


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章