页面循环引用解决

804 阅读3分钟

循环引用之前也是我一个比较讨厌的地方,这种问题一般不会导致你的页面奔溃,但是它会产生偶然性奔溃,所以在没有其他更紧急的事情的情况下这种问题也是一定要解决的。 以下提供以下循环引用的解决办法:

一、instruments

xy让我找一下详情的循环引用,我擦!2000+以上的代码,还不是我写的,当然首选instruments 工具分析一下啦,比较快么 打开xcode--product--profile 点击 leaks 点击你要查看的循环引用的页面就可以帮你找到相关循环引用的代码,把相关代码改成弱引用就行

优点:快,不费事
缺点:也是太快,有一些发现不了,需要人工观察

所以如果检查循环引用,这个最好放到第一步 (instruments工具用法网上很多,我还是附带一个吧,供大家参考:Instruments检测解决iOS内存泄露

二、RAC的循环引用

RAC是很方便,但是也有一点有点坑呀(也是我自己粗心,想当然啊), @weakify(self) 我刚开始用的时候认为他就是相当于—weak的作用,还觉得挺方便,都用改写self直接能弱引用,这不是神器是什么? 后来呵呵了🙄,只加一个@weakify(self) 你下面的代码 self 必须要替换成 self_weak 才会起作用 ,如果想要self弱引用 则 必须要 加上 @strongify(self) ,否则 你的代码里 大片大片的循环引用 就产生了 具体原因是什么 我是参考的xy 提供剖析RAC中的@weakify、@strongify 文档知道的

三、暴力修改

这个方法是xy发现的,我觉得这个办法面对一大片代码又找不到 推荐使用 : 把代码里面 self 全部替换 成 wself 然后根据报错慢慢改 这个方法解决self 的循环还是不错的,很爽呀(慎用)

四:非self的循环引用

除了 VC 的循环引用 如果有时间的话 尽量 把 写的其他的类 都检查一下 循环引用 ,可能作用没有 vc 那么明显,但是 聊胜于无 。 通过排查 发现 日历页 每一个类都释放了 除了 HotelChoiceChildAgeView 类 不调用 dealloc 但是这个类代码非常简单,本身没有循环引用 一共不到100行,里面我也都是找过的 那么就是有可能使用这个类的地方强引用了,查找之后发现

AgeView *child = [AgeView new];
                child.sequenceLab.text = [NSString stringWithFormat:@"第%@位",[self intergerToChinese:i]];
                [arrM addObject:child];
                @weakify(self)
                [[child rac_signalForControlEvents:UIControlEventTouchUpInside]subscribeNext:^(__kindof UIControl * _Nullable x) {
                    @strongify(self)
                    [self choiceAge:child index:(i-1)];
                }];

这个block内部之前 写了 @strongify(self) ,但是 这个方法还同时引用的 child 所以 chlid 也需要弱引用,这样才能保证 HotelChoiceChildAgeView 能够释放 改成:

AgeView *child = [AgeView new];
                child.sequenceLab.text = [NSString stringWithFormat:@"第%@位",[self intergerToChinese:i]];
                [arrM addObject:child];
                @weakify(self,child)
                [[child rac_signalForControlEvents:UIControlEventTouchUpInside]subscribeNext:^(__kindof UIControl * _Nullable x) {
                    @strongify(self,child)
                    [self choiceAge:child index:(i-1)];
                }];

所以self 不释放 还有可能是别的类强引用了它。 最好的方法还是需要自己每个类下面断点一个dealloc,每次都注意是否释放,否则任务量移到后面,出了问题也不容易找到

以上仅本人经验,请轻喷~