WKWebView添加腳本信息處理
在交互的過程中,我們可能會需要和網頁交互,其中一條是可以在網頁中注入腳本,添加腳本信息處理,其中比較常用的一個方法是WKUserContentController里面的:
- (void)addScriptMessageHandler:(id <WKScriptMessageHandler>)scriptMessageHandler name:(NSString *)name
我們的scriptMessageHandler如果直接用的self的話,必須在合適的地方使用
removeScriptMessageHandlerForName:
移除,如果不移除,dealloc方法不會執(zhí)行,所在控制器無法釋放.
錯誤的移除方法
為了將其移除,我在視圖將要出現時添加腳本信息處理,視圖將要消失的時候移除腳本信息處理,而這種方法是錯誤的.事實表明,在部門ios設備和系統(tǒng)上會有不確定性表現.有可能造成網頁無法正常顯示.
正確的移除方法
先找到原因:WKUserContentController 對這個腳本消息處理代理是強引用,而不是若引用.因此當我們把代理直接設置為當前控制器時,就會造成循環(huán)引用.因此代理設置成若引用才行.而直接使用~~~~__weak typeof(self) WeakSelf = self;~~~~是不可行的.
因此正確的方法是單獨創(chuàng)建一個類,設置一個弱引用的代理.就可以正確釋放了
@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];
我們的代理會執(zhí)行你在控制器中寫的代理方法的,這一點源于我們WeakScriptMessageHandler對didReceiveScriptMessage的實現,self.delegate這個若引用引用的就是當前所在的控制器.