UIWebview关于JSContext所遇到的问题

iOS7以后,苹果加入了JSContext来处理JavaScript,实现h5页面和原生的交互。之前项目中经常会用到JSContext,也遇到了很多问题,现在刚好有时间,把遇到的问题正好记录下来。

一.JSContext循环引用导致不释放的问题

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,彼此等待对方造成了循环引用的问题,尽管使用了weakSelf,还是不会解除这种状态。

1.2 解决方法

本人是通过创建一个中间对象来实现的,代码如下:

    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的创建方法,在viewDidLoad创建

_weakWebJSExportDelegate = [[WeakWebJSExportDelegate alloc] initWithDelegate:self];

WeakWebJSExportDelegate的实现


UIWebview关于JSContext所遇到的问题_第1张图片
454FB2D1-14DC-4761-962C-F1935D150A92.png

如上图所示,BTNVSetTitle是h5调用app的方法,引入Back2ObjcDelegate是为了让该方法的执行还是在webview里面实现。

二.UIWebview调用reload导致JSContext失效的问题

2.1 遇到的问题

当页面刷新或者跳转新页面,shouldStartLoadWith与webViewDidStartLoad获取的均为上一个页面的JSContext。而webviewDisFinishLoad触发的时候,获取虽然是正确的JSContext,但是此时页面已经加载完毕,js方法已经调用完了,获取到正确的值也没用了,所以就导致了JSContext失效的问题。

2.2 解决方法

需要刷新的时候重新创建一个webview,同时删掉老的webview,这样新的webview获取JSContext的时候不会获取到老的,那么正确的JSContext就能正确设置JS对象。

你可能感兴趣的:(UIWebview关于JSContext所遇到的问题)