iOS - 记录一次内存泄漏
2023-04-18 14:39:43 时间
一· 屋漏偏逢连夜雨(全都漏了)
起因 :
因有需求需要绑定微信账号并对接微信SDK时候发现
1. 调用sendReq
[WXApi sendReq:req completion:^(BOOL success) {
}];
2. 接收到回调 此方法只在Appdelegate.m 处出发 因为sdk在初始化时候注册 [WXApi registerApp:WECHAT_APPID universalLink:UNIVERSALLINK];
- (void)onResp:(BaseResp *)resp{
}
问题发现:
发现经过 由于业务需求需要有绑带微信&登录微信两个功能 实际上访问的是同一个登陆接口路由
由于微信sdk回调 onResp只在Appdelegate.m , 那么解决方案我选择KVO 。
当我调用sdk-确认授权-触发回调的时候 KVO这两个登录和绑定监听同时触发
[[NSNotificationCenter defaultCenter] postNotificationName:@"weChatLoing" object:dict];
[[NSNotificationCenter defaultCenter] postNotificationName:@"weChatBinding" object:dict];
问题分析:
基本上确定上内存泄漏,问题是泄漏点在哪,自此开始了漫长的排查
尝试解决:
从dealloc开始入手
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self]; //打断点
}
考虑到当前对象既vc无法准确定位到内存泄漏到地方 只能从生命周期开始入手一个一个地方找
viewDidload
- (void)viewDidLoad {
[super viewDidLoad];
[self 网络请求];
[self initUI];
[self 登录:@"1" 密码:@"1"];
// [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(登录监听) name:@"微信监听" object:nil];
// [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(绑定监听) name:@"绑定监听" object:nil];
[self 三分SDK初始化];
}
找到问题关键
[AgoraRtm classMethod:Token user:uid completion:^(AgoraRtmLoginErrorCode errorCode) {
if (errorCode == AgoraRtmLoginErrorOk || errorCode == AgoraRtmLoginErrorAlreadyLogin) {
[AgoraRtm setStatus:LoginStatusOnline];
}else{
}
}];
最终定位到自己定义的声网sdk类方法setStatus
内存泄漏点(二)
configure.customAreaView = ^(UIView * _Nonnull customAreaView) {
UIButton *btn = [[UIButton alloc]init];
btn.frame = CGRectMake(0,0,self.view.bounds.width,200);
[btn addTarget:self action:@selector(fff) forControlEvents:UIControlEventTouchUpInside];
}
泄漏原因排查:
初步排查原因于button控件添加target的时候对当前对象引用,但同时SDK内部猜测可能有Runtime持有当前对象或者是异步并发线程处理数据时候也引用了当前对象,导致sdk内部自定义的customAreaView中添加button的target时导致内存泄漏,解决办法变成WeakSelf弱引用即可。
内存泄漏点(三)
原因排查: 当前对象对自定义弹框引用
解决办法:解偶
- (diyView *)diy {
if (!_diy) {
_diy = [[diyView alloc]init];
_diy.delegate = self;
_diy.frame = CGRectMake(0, 0, 200, 200);
}
return _diy;
结论:由于弹框使用时机不确定,当时选择作为一个对象懒加载进来的想法是错误的,代码需要保持一定的整洁,尽可能做到减少self的使用,以达到接偶的目的,此次泄漏情况的原因是由于sdk类方法定义失误导致后继代码使用self的地方一并泄漏
内存泄漏点(四)
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(kvo) name:@"kvo" object:nil];
在dealloc处remove监听不要以为就万事大吉.此处内存泄漏狠狠地打了我一脸
结论:KVO/KVC 监听需要满足情况下才能使用。1.对当前对象对生命周期足够把握 2.尽可能不使用监听 因为内存泄漏十有八九是kvo block 这些会延长生命周期的方法
相关文章
- 【技术种草】cdn+轻量服务器+hugo=让博客“云原生”一下
- CLB运维&运营最佳实践 ---访问日志大洞察
- vnc方式登陆服务器
- 轻松学排序算法:眼睛直观感受几种常用排序算法
- 十二个经典的大数据项目
- 为什么使用 CDN 内容分发网络?
- 大数据——大数据默认端口号列表
- Weld 1.1.5.Final,JSR-299 的框架
- JavaFX 2012:彻底开源
- 提升as3程序性能的十大要点
- 通过凸面几何学进行独立于边际的在线多类学习
- 利用行动影响的规律性和部分已知的模型进行离线强化学习
- ModelLight:基于模型的交通信号控制的元强化学习
- 浅谈Visual Source Safe项目分支
- 基于先验知识的递归卡尔曼滤波的代理人联合状态和输入估计
- 结合网络结构和非线性恢复来提高声誉评估的性能
- 最佳实践丨云开发CloudBase多环境管理实践
- TimeVAE:用于生成多变量时间序列的变异自动编码器
- 具有线性阈值激活的神经网络:结构和算法
- 内网渗透之横向移动 -- 从域外向域内进行密码喷洒攻击