Osheep

时光不回头,当下最重要。

delegate的简单使用+部分细节探究

代理模式在iOS开发中是一种常见的设计模式,简单的说就是,有一件事,A做不了,声明一个协议,B帮A做,但是B只能做A协议中规定的事情,这就是代理模式

具体在iOS中的使用:一般是 值回传(跨一级),因为值顺传的话,直接在前一个VC set过去就行了!

《delegate的简单使用+部分细节探究》

made in 小蠢驴的配图

项目简单介绍:

  • A –> push B,点击B的按钮, B popTo A,同时,B要把 B 自己的数据, 回传到前一个页面 A上!

  • B -> A,最终的结果是A接收 B回传的数据,所以A应该是执行者,B发布委托,A帮忙执行!

由于值的回传 -> 不能set,最好用Block 或 delegate,用通知不推荐,效率比较低!


1. 在委托类中,声明协议,以及代理方法!(委托类 -> 要做Pop操作的那个类!)
《delegate的简单使用+部分细节探究》

协议的声明
2. 声明协议后,在委托类的.h的文件中,还要声明一波代理 – 用weak!!
《delegate的简单使用+部分细节探究》

代理声明
3. 在委托类的.m文件中,让代理实现协议中的方法!
《delegate的简单使用+部分细节探究》

代理调用方法
4. 真正实现 方法的 – 是 接收委托的类!
《delegate的简单使用+部分细节探究》

接受委托的类
5. 声明代理之后,设置代理对象 == 当前控制器
《delegate的简单使用+部分细节探究》

设置代理
解释:
《delegate的简单使用+部分细节探究》

代理指向
6. 真正实现方法
《delegate的简单使用+部分细节探究》

真正实现方法
7. 解释:调用实现方法的地方 – 因为没写 [self xxx]
《delegate的简单使用+部分细节探究》

代理方法的调用处
在委托类中,已经实现了调用!

B 的 _delegate 调用的 XXX , B 的_delegate 是A,等价于 帮A 调用了 [self XXX]!!!


–测试:为何delegate 声明的时候都用weak,不用strong?

–怀疑:B stong-> 指向 delegate,A指向delegate ,导致retain cycle?

探究如下:

使用strong 也 没产生循环引用?

《delegate的简单使用+部分细节探究》

测试使用dealloc

没有导致循环引用的原因!

《delegate的简单使用+部分细节探究》

测试原因.png

测试:

《delegate的简单使用+部分细节探究》

设置strong->指向成员变量:demoVC
《delegate的简单使用+部分细节探究》

强引用控制器指向

测试结果如下:

《delegate的简单使用+部分细节探究》

发现retain cycle

解决办法 -> strong ->weak?

《delegate的简单使用+部分细节探究》

修改strong -> weak

测试结果如下:

《delegate的简单使用+部分细节探究》

测试发现:retain cycle还存在

解释:当前的VC 是 navigationController 的 rootVC,所以肯定是不会被销毁的! –>因为一直不会被销毁–>导致,VC 强引用指向的 demoVC也不会被销毁,一直存在!


正确的测试方法!
rootVC -> twoVC , towVC -> push == ViewController,VC -> push == DemoVC! –> 测试 VC 与 Demo,忽略 twoVC(rootVC)

《delegate的简单使用+部分细节探究》

使用strong

strong 修饰的weak

《delegate的简单使用+部分细节探究》

改为weak修饰delegate 之后
《delegate的简单使用+部分细节探究》

控制器得成功释放

解决循环引用问题 –> 还是得用weak 修饰 delegate!

前提条件:

《delegate的简单使用+部分细节探究》

前提条件说明

解释如下:

《delegate的简单使用+部分细节探究》

原因

注意:构成循环引用的充要条件是,两个VC相互强引用,如果 一个demoVC是简单的alloc init出来的控制器,在当前的控制器并未对其强引用的情况下,就算delegate 使用 strong,也只有一边是strong!


题外话:代理能否跨级传递?

test:A -> B -> C,C实现方法,popToRootVC (–>A),让A实现其方法,是否可以?

这里的A == twoVC;B = ViewController;C = DemoVC

  1. 在 C(DemoVC)中 声明协议 + 代理

    《delegate的简单使用+部分细节探究》

    新增协议+代理
  2. 打算成为代理控制器的rootVC – twoVC

    《delegate的简单使用+部分细节探究》

    TwoVC成为代理,实现代理方法

    正常逻辑,应该是可以行得通的,demoVC声明,twoVC实现,twoVC当demoVC的代理执行,delegate也设置好了,只差一步!

    这样设置,没有push的话,delegate 是 设置不过去的!!


–>测试:在demoVC中,接收delegate测试

《delegate的简单使用+部分细节探究》

测试delegate的set

只有在VC push的时候,才能进

《delegate的简单使用+部分细节探究》

必须push!

因为有push才能设置进去值!

《delegate的简单使用+部分细节探究》

push才能进方法

在TwoVC中,因为跳转到的是ViewController,不是 demoVC,值设置不进去,但是如果让TwoVC直接push到demoVC的话,又不符合实际需求,因为实际需求是 twoVC -> ViewController -> demoVC!

所以,delegate 不能实现跨级传递 ->block同理 –> 解决办法 :通知(Notifation)!

点赞