国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > iOS > 正文

iOS WKWebView中MessageHandler內存泄漏問題的完美解決過程

2019-10-21 18:40:22
字體:
來源:轉載
供稿:網友

背景

項目中使用了WKWebView替換了之前的UIWebView,牽扯到Hybird開發,我們需要和H5交互,所以用到了WKWebViewConfiguration 中的 WKUserContentController

所以初始化代碼如下

  WKUserContentController *userContentController = [[WKUserContentController alloc] init];  [userContentController addScriptMessageHandler:self name:GetKeyiOSAndroid_Action];  [userContentController addScriptMessageHandler:self name:Upload_Action];  // WKWebView的配置  WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];  configuration.userContentController = userContentController;  _webView = [[WKWebView alloc] initWithFrame:CGRectZero configuration:configuration];  _webView.navigationDelegate = self;  _webView.UIDelegate = self;

GetKeyiOSAndroid_Action Upload_Action 分別是H5通過message handler的方式來調用OC的兩個方法。

這時,就已經發生了隱患,因為

[userContentController addScriptMessageHandler:self name:GetKeyiOSAndroid_Action];

這里userContentController持有了self ,然后 userContentController 又被configuration持有,最終唄webview持有,然后webview是self的一個私有變量,所以self也持有self,所以,這個時候有循環引用的問題存在,導致界面被pop或者dismiss之后依然會存在內存中。不會被釋放

當然如果你只是靜態界面,或者與H5的交互的內容僅限于本頁面內的內容,其實只是單純的內存泄漏,但是,如果此時和H5的交互方法中牽扯到全局變量,或者全局的一些內容,那么就不可控制了。

我發現這個問題是因為我們web頁面會監聽token過期的和登錄狀態改變的通知,然后會刷新界面,并且重新發送請求,這一系列動作中會和用戶的全局信息進行交互,所以在訪問一個web頁面后,切換賬號登錄時會發現有之前訪問過的web頁面請求發出,并且因為token不同報了token過期的錯誤,所以導致登錄后誤操作為token過期,緊接著被踢到登錄界面。

通過charles抓包發現,這些web頁面都是在切換登錄賬號欠訪問的所有界面,所以,鎖定問題時web頁面依舊存在,在切換登錄后收到了登錄狀態改變的通知,重新刷新了界面導致請求發出并返回報錯,進而出現登錄后被踢出的bug。

解決方案:

既然是循環引用,那么必須破除一邊的強引用,改為弱引用,或者直接去除引用。思路明朗了。。

嘗試1:

id __weak weakSelf = self;WKUserContentController *userContentController = [[WKUserContentController alloc] init];[userContentController addScriptMessageHandler:weakSelf name:GetKeyiOSAndroid_Action];

思路效仿block , 結果失敗

嘗試2:

在viewWillDisappear / viewDidDisappear 生命周期方法中調用

[_webView.configuration.userContentController removeAllUserScripts];

這算一個腦抽的嘗試,看文檔說明就懂了。自行略過

iOS,WKWebView,MessageHandler,內存泄漏

嘗試3:

不在初始化時添加ScriptMessageHandler, 而是和Notificenter/KVC一個思路

- (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; [_webView.configuration.userContentController addScriptMessageHandler:self name:GetKeyiOSAndroid_Action]; [_webView.configuration.userContentController addScriptMessageHandler:self name:Upload_Action];}- (void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; [_webView.configuration.userContentController removeScriptMessageHandlerForName:GetKeyiOSAndroid_Action]; [_webView.configuration.userContentController removeScriptMessageHandlerForName:Upload_Action];}

結果成功

小結:

之前在使用WKWebView的時候很多blog的內容都只是說了怎么添加Message Handler 但是并沒有高速大家有這個內存泄漏的風險,如果你只是頁面內的數據調用你壓根都不會發現這個問題。

此坑已填!

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對VEVB武林網的支持。


注:相關教程知識閱讀請移步到IOS開發頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 乌鲁木齐县| 山东省| 沂水县| 宜黄县| 南充市| 梁山县| 荃湾区| 晋江市| 梅河口市| 新兴县| 德阳市| 衡东县| 平潭县| 奉化市| 北川| 林州市| 克拉玛依市| 湟中县| 富民县| 武义县| 明星| 黄浦区| 鸡东县| 汶川县| 汉中市| 临汾市| 武夷山市| 泾川县| 宜昌市| 蕲春县| 博野县| 贺州市| 集贤县| 大竹县| 扎鲁特旗| 远安县| 璧山县| 油尖旺区| 承德县| 商城县| 临武县|