内存问题主要讨论WKUserContentController
添加
下面导致的问题
WKUserContentController
持有self
,
WKWebViewConfiguration
持有WKUserContentController
WkWebView
持有WKWebViewConfiguration
self
持有WkWebView
[userCC addScriptMessageHandler:self name:@"nativeObj"];
循环持有导致的内存无法释放,表现来看是dealloc
没有执行
- (void)dealloc
{
NSLog(@"dealloc");
}
解决方案
在WKUserContentController
持有self,中间建立弱引用weak
- 核心代码
- .h
@interface WeakWebScriptMessageDelegate : NSObject<WKScriptMessageHandler>
@property (nonatomic, weak) id<WKScriptMessageHandler> scriptDelegate;
- (instancetype)initWithDelegate:(id<WKScriptMessageHandler>)scriptDelegate;
@end
- .m
@implementation WeakWebScriptMessageDelegate
- (instancetype)initWithDelegate:(id<WKScriptMessageHandler>)scriptDelegate {
self = [super init];
if (self) {
_scriptDelegate = scriptDelegate;
}
return self;
}
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
[self.scriptDelegate userContentController:userContentController didReceiveScriptMessage:message];
}
-(void)dealloc{
NSLog(@"%@ -- dealloc",self.class);
}
WeakWebScriptMessageDelegate *de = [[WeakWebScriptMessageDelegate alloc]initWithDelegate:self];
[configuration.userContentController addScriptMessageHandler:de name:@"getUserId"];
在引用地方,将self被里面的scriptDelegate
持有,因为scriptDelegate
是weak修饰,
因此userContentController
强持有WeakWebScriptMessageDelegate
而WeakWebScriptMessageDelegate
弱持有self
。
控制器dealloc
可以正常打印,但是WeakWebScriptMessageDelegate
没有被释放,因为WeakWebScriptMessageDelegate
中注册了一些name,需要在dealloc
移除
- (void)dealloc
{
NSLog(@"dealloc");
if (@available(iOS 14.0, *)) {
[[_webView configuration].userContentController removeAllScriptMessageHandlers];
} else {
// Fallback on earlier versions
}
//[[_webView configuration].userContentController removeScriptMessageHandlerForName:@"closeMe"];
}
网友评论