WKWebView添加脚本信息处理
在交互的过程中,我们可能会需要和网页交互,其中一条是可以在网页中注入脚本,添加脚本信息处理,其中比较常用的一个方法是WKUserContentController里面的:
- (void)addScriptMessageHandler:(id <WKScriptMessageHandler>)scriptMessageHandler name:(NSString *)name
我们的scriptMessageHandler如果直接用的self的话,必须在合适的地方使用
removeScriptMessageHandlerForName:
移除,如果不移除,dealloc方法不会执行,所在控制器无法释放.
错误的移除方法
为了将其移除,我在视图将要出现时添加脚本信息处理,视图将要消失的时候移除脚本信息处理,而这种方法是错误的.事实表明,在部门ios设备和系统上会有不确定性表现.有可能造成网页无法正常显示.
正确的移除方法
先找到原因:WKUserContentController 对这个脚本消息处理代理是强引用,而不是若引用.因此当我们把代理直接设置为当前控制器时,就会造成循环引用.因此代理设置成若引用才行.而直接使用~~~~__weak typeof(self) WeakSelf = self;~~~~是不可行的.
因此正确的方法是单独创建一个类,设置一个弱引用的代理.就可以正确释放了
@interface WeakScriptMessageHandler : NSObject <WKScriptMessageHandler>
@property (nonatomic, weak)id<WKScriptMessageHandler>delegate;
-(instancetype)initWithDelegate:(id<WKScriptMessageHandler>)delegate;
@end
@implementation WeakScriptMessageHandler
-(instancetype)initWithDelegate:(id<WKScriptMessageHandler>)delegate{
if (self = [super init]) {
_delegate = delegate;
}
return self;
}
-(void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message{
[self.delegate userContentController:userContentController didReceiveScriptMessage:message];
}
@end
使用的时候,这样就可以了
[userContent addScriptMessageHandler:[[WeakScriptMessageHandler alloc]initWithDelegate:self] name:messageHandleName];
我们的代理会执行你在控制器中写的代理方法的,这一点源于我们WeakScriptMessageHandler对didReceiveScriptMessage的实现,self.delegate这个若引用引用的就是当前所在的控制器.