iOS7以后,蘋果加入了JSContext來處理JavaScript誉碴,實(shí)現(xiàn)h5頁面和原生的交互蜘澜。之前項(xiàng)目中經(jīng)常會用到JSContext,也遇到了很多問題,現(xiàn)在剛好有時(shí)間慨飘,把遇到的問題正好記錄下來确憨。
一.JSContext循環(huán)引用導(dǎo)致不釋放的問題
1.1 遇到的問題
self.jsContext = [_webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
self.jsContext[@"app"] = weakSelf;
self.jsContext.exceptionHandler = ^(JSContext *context, JSValue *exceptionValue) {
context.exception = exceptionValue;
NSLog(@"異常信息:%@", exceptionValue);
};
如上代碼所示,JSContext引用了self,self又引用了JSContext瓤的,彼此等待對方造成了循環(huán)引用的問題休弃,盡管使用了weakSelf,還是不會解除這種狀態(tài)。
1.2 解決方法
本人是通過創(chuàng)建一個(gè)中間對象來實(shí)現(xiàn)的圈膏,代碼如下:
self.jsContext = [_webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
self.jsContext[@"app"] = _weakWebJSExportDelegate;
self.jsContext.exceptionHandler = ^(JSContext *context, JSValue *exceptionValue) {
context.exception = exceptionValue;
NSLog(@"異常信息:%@", exceptionValue);
};
_weakWebJSExportDelegate的創(chuàng)建方法,在viewDidLoad創(chuàng)建
_weakWebJSExportDelegate = [[WeakWebJSExportDelegate alloc] initWithDelegate:self];
WeakWebJSExportDelegate的實(shí)現(xiàn)
如上圖所示,BTNVSetTitle是h5調(diào)用app的方法塔猾,引入Back2ObjcDelegate是為了讓該方法的執(zhí)行還是在webview里面實(shí)現(xiàn)。
二.UIWebview調(diào)用reload導(dǎo)致JSContext失效的問題
2.1 遇到的問題
當(dāng)頁面刷新或者跳轉(zhuǎn)新頁面稽坤,shouldStartLoadWith與webViewDidStartLoad獲取的均為上一個(gè)頁面的JSContext丈甸。而webviewDisFinishLoad觸發(fā)的時(shí)候糯俗,獲取雖然是正確的JSContext,但是此時(shí)頁面已經(jīng)加載完畢睦擂,js方法已經(jīng)調(diào)用完了得湘,獲取到正確的值也沒用了,所以就導(dǎo)致了JSContext失效的問題顿仇。
2.2 解決方法
需要刷新的時(shí)候重新創(chuàng)建一個(gè)webview淘正,同時(shí)刪掉老的webview,這樣新的webview獲取JSContext的時(shí)候不會獲取到老的臼闻,那么正確的JSContext就能正確設(shè)置JS對象鸿吆。