block 与delegate 的区别

来源:互联网 发布:我好想你网络热播视频 编辑:程序博客网 时间:2024/04/19 21:11

Block 和 Delegate中的方法都可以理解成回调函数,当某件事情发生的时候取执行一段代码片段

无论是block还是delegate模式本质上都是回调,使用block,其优点是回调的block代码块直接就放在了block赋值的地方,使代码更为紧凑,缺点是block内使用到当前类的实例变量的时候,需要注意循环引用的问题,即需要使用__block(MRC下)或者__weak(ARC下)定义一个弱引用的self出来,block里面使用弱引用的self去操作属性或调用方法。delegate模式不用像block一样做特殊处理,但是如果多个对象设置的代理是同一个对象,就需要在delegate方法中判断当前执行代理的是哪个对象。

         1.当回调函数多于3个的时候,采用代理比较好

         2.使用代码块容易造成循环引用,代理不会出现该问题

         3.其他情况下优先考虑代码块

1.从源头上理解和区别block和delegate

delegate运行成本低,block的运行成本高。

block出栈需要将使用的数据从栈内存拷贝到堆内存,当然对象的话就是加计数,使用完或者block置nil后才消除。delegate只是保存了一个对象指针,直接回调,没有额外消耗。就像C的函数指针,只多做了一个查表动作。

2.从使用场景区别block和delegate

有多个相关方法。假如每个方法都设置一个 block, 这样会更麻烦。而 delegate 让多个方法分成一组,只需要设置一次,就可以多次回调。当多于 3 个方法时就应该优先采用 delegate。当1,2个回调时,则使用block。

delegate更安全些,比如: 避免循环引用。使用 block 时稍微不注意就形成循环引用,导致对象释放不了。这种循环引用,一旦出现就比较难检查出来。而 delegate 的方法是分离开的,并不会引用上下文,因此会更安全些。

delegate回调返回的参数被限制在了 NS 类的范围内,数量也很有限(当然可以用直接调用方法的形式在绕过,并不推荐;也可以用 Array 套着传, 不过这样需要有文档支持,不然不够清晰,回调方法也需要独立的验证,故也不推荐)。


通过上面的知识,可以简单说他们的区别,block适合少数回调,需要运行内存,多次回调容易出现循环引用 delegate回调次数不限制,回调对象需要知道当前回调对象,delegate很安全不会引用上下文。


3>Block变量在ARC和MRC环境下的生命周期


ARC环境下打印结果如下:


分析原因如下:

 //1.分析,ARC如果在块对象中使用了__block指定的变量,那么这个变量将会被copy到堆内存中,并且原变量也会指向这个堆内存中的空间

//2.如果有两个块对象引用了同一个__block指定的变量,那么他们共享这个变量,共享同一个内存


MRC环境下打印结果如下:



分析原因如下:


//1.函数内被__block修饰的变量可以被块对象读写,多个块对象之间可以共享__block变量的值

//2.__block变量不是静态变量,在块句法每次用到这种变量的时候会去相应的内存空间获取值,就是说不同块对象分享的__block变量的值是执行时动态生成

//3.访问__block变量的块对象被复制后,新生成的块对象也能共享__block变量的值

//4.多个块对象访问同一个__block变量的时候,只要有一个块对象存在,__block变量就会存在;如果访问__block变量的对象都不存在了,__block对象随之消失


//总结:

//注意:因为__block变量的内存位置可能会发生变化,所以,写程序时候不要写用指针访问__block变量的代码,那样可能会得不到预期的结果(这是在项目中尤为重要的一点)



原创粉丝点击