问题:block和代理的区别,哪个更好?
2020-05-08 本文已影响0人
姜小舟
block和代理本质上是不同的,因为block其实是一个对象,代理是一种设计模式(委托-代理模式)。这里主要是把block和代理作为回调的两种方式,在应用场景上进行比较。
block和代理的区别
- block的代码可读性更好。因为block只要实现就可以了,而代理需要遵守协议并且实现协议里的方法,而两者不在一个地方。
- 代理使用起来也更麻烦,因为要声明协议、声明代理属性、遵守协议、实现协议里的方法。block不需要声明,也不需要遵守,只需要声明属性和实现就可以了。
- block是一种轻量级的回调,可以直接访问上下文,由于block的代码是内联的,运行效率更高。
- block就是一个对象,实现了匿名函数的功能。所以我们可以把block当做一个成员变量、属性、参数使用,使用起来非常灵活。
像用AFNetworking请求数据和GCD实现多线程,都使用了block回调。
- blcok的运行成本高,会延长对象的生命周期。block出栈需要将使用的数据从栈内存拷贝到堆内存,当然对象的话就是引用计数加1,使用完或者block置nil后才销毁。
- delegate只是保存了一个对象指针(一定要用week修饰delegate,不然也会循环引用),直接回调,没有额外消耗。就像C的函数指针,只多做了一个查表动作。
- block容易造成循环引用,而且不易察觉。
哪个更好?
block和代理都各有优缺点。block为苹果后期引入,引入后大量API都对原有delete进行Block的封装,所以笔者认为Apple自身是比较倾向于Block的。
- 优先但谨慎使用block。
- 如果回调的状态很多,多于三个使用代理。
- 如果回调的很频繁,次数很多,像UITableview,每次初始化、滑动、点击都会回调,使用代理。
- 为了避免循环引用,也可以使用 delegate。使用 block 时稍微不注意就形成循环引用,导致对象释放不了。这种循环引用,一旦出现就比较难检查出来。而 delegate 的方法是分离开的,并不会引用上下文,因此会更安全些。假如写一个库供他人使用,不清楚使用者的水平如何。这时为防止误用,宁愿麻烦一些,笨一些,使用 delegate 来替代 block。