项目中使用了WKWebView替换了之前的UIWebView,牵扯到湘研开发,我们需要和H5交互,所以用到了WKWebViewConfiguration中的WKUserContentController
所以初始化代码如下
WKUserContentController * userContentController=[[WKUserContentController alloc] init); [userContentController addScriptMessageHandler:自己的名字:GetKeyiOSAndroid_Action]; [userContentController addScriptMessageHandler:自己的名字:Upload_Action];//WKWebView的配置 WKWebViewConfiguration *配置=[[WKWebViewConfiguration alloc] init); 配置。userContentController=userContentController; _webView=[[WKWebView alloc] initWithFrame: CGRectZero配置:配置); _webView。navigationDelegate=自我; _webView。UIDelegate=自我;
GetKeyiOSAndroid_Action Upload_Action分别是H5通过消息处理程序的方式来调用OC的两个方法。
这时,就已经发生了隐患,因为
<代码> [userContentController addScriptMessageHandler:自己的名字:GetKeyiOSAndroid_Action]; 代码>
这里userContentController持有了自我,然后userContentController又被配置持有,最终呗webview持有,然后webview是自我的一个私有变量,所以自我也持有自我,所以,这个时候有循环引用的问题存在,导致界面被流行或者解散之后依然会存在内存中。不会被释放
当然如果你只是静态界面,或者与H5的交互的内容仅限于本页面内的内容,其实只是单纯的内存泄漏,但是,如果此时和H5的交互方法中牵扯到全局变量,或者全局的一些内容,那么就不可控制了。
我发现这个问题是因为我们web页面会监听牌过期的和登录状态改变的通知,然后会刷新界面,并且重新发送请求,这一系列动作中会和用户的全局信息进行交互,所以在访问一个web页面后,切换账号登录时会发现有之前访问过的web页面请求发出,并且因为令牌不同报了令牌过期的错误,所以导致登录后误操作为令牌过期,紧接着被踢到登录界面。
通过查尔斯抓包发现,这些web页面都是在切换登录账号欠访问的所有界面,所以,锁定问题时web页面依旧存在,在切换登录后收到了登录状态改变的通知,重新刷新了界面导致请求发出并返回报错,进而出现登录后被踢出的错误。
既然是循环引用,那么必须破除一边的强引用,改为弱引用,或者直接去除引用。思路明朗了. .
<强>尝试1:强>
id __weak weakSelf=自我; WKUserContentController * userContentController=[[WKUserContentController alloc] init); [userContentController addScriptMessageHandler: weakSelf名称:GetKeyiOSAndroid_Action];
思路效仿块,结果失败
<强>尝试2:强>
在viewWillDisappear/viewDidDisappear生命周期方法中调用
[_webView.configuration。userContentController removeAllUserScripts];
这算一个脑抽的尝试,看文档说明就懂了。自行略过
<强>尝试3:强>
不在初始化时添加ScriptMessageHandler,而是和Notificenter/现有的一个思路
- (void)那些:(BOOL)动画{ (超级那些:动画); [_webView.configuration。userContentController addScriptMessageHandler:自己的名字:GetKeyiOSAndroid_Action]; [_webView.configuration。userContentController addScriptMessageHandler:自己的名字:Upload_Action]; } - (void) viewWillDisappear: (BOOL)动画{ (超级viewWillDisappear:动画); [_webView.configuration。userContentController removeScriptMessageHandlerForName GetKeyiOSAndroid_Action):; [_webView.configuration。userContentController removeScriptMessageHandlerForName Upload_Action):; }
结果成功
<强>小结:强>
之前在使用WKWebView的时候很多博客的内容都只是说了怎么添加消息处理程序但是并没有高速大家有这个内存泄漏的风险,如果你只是页面内的数据调用你压根都不会发现这个问题。
此坑已填!
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对的支持。