NSInvalidArgumentException、内存泄漏、CAAnimationDelegate
最近遇到bugly上报错NSInvalidArgumentException,在解决时遇到了些许问题,同时也对内存泄漏有了些认识,做个复盘,总结下经验。
内存泄漏(Memory Leak)是指程序中己动态分配的堆内存由于某种原因程序未释放或无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至导致内存溢出、系统崩溃等严重后果。
1.遇到 NSInvalidArgumentException报错详细为WKWebView was deallocated while key value observers were still registered with it. 基本就是说WKWebView在销毁时,他的key还被观察着。所以立马想到是不是在类的dealloc方法没有removeObserver(Observer有add须对应remove)。code review,发现是有写移除代码的。所以猜测是不是有内存泄漏的情况导致dealloc没有被执行。
2.内存泄漏一般是有些循环引用,对应到代码一般是block中self使用不当、delegate使用strong修饰、timer没有及时invalidate。所以从这3个方面进行code review。无果!
3.想到之前使用过的的MLeaksFinder,可以检测疑似循环引用的点并且提示。将其引用到项目中找到了疑似的内存泄漏点。
4.对其中的类进行code review 无果
5.隔日code review发现block用到了未weak的self,修改,内存泄漏提示消除
- (void)addTapAction {
DEFINE_WEAK_SELF
[self bk_whenTapped:^{
if (!weakSelf.object.isAd) {
[weakSelf updateTitleColorWithRead:YES];
}
[weakSelf didTapCellActionWithObject:weakSelf.object];
}];
}
NSInvalidArgumentException错误修复
6.尝试寻找项目中其他的内存泄漏点,又在项目中经常出现crash的类中寻找到一条,最后寻找是在CAAnimation动画的使用中,因为动画为循环,且涉及2个CAAnimationGroup的切换,所以必须有CAAnimationDelegate方法,但是这个delegate是强引用
@property(nullable, strong) id delegate;
摆在我的面前有2个选择 要么改变动画的写法,不用CAAnimation,要么就是在不必要时将delegate置为nil 需要时再设置并开启动画。最终选择了后者,毕竟这个是个比较坑的系统设定,要尝试解决下它。
-(void)removedelegate{
self.iconGroup.delegate = nil;
self.imageGroup.delegate = nil;
[self.imageLayer removeAnimationForKey:@"icon"];
}
-(void)adddelegate{
self.iconGroup.delegate = self;
self.imageGroup.delegate = self;
[self.imageLayer addAnimation:self.iconGroup forKey:@"icon"];
}
在viewWillDisappear移除,在viewWillAppear添加。这样业务不出错,并且可以解决循环引用