我不确定自己是在WebKit
中遇到了一个bug还是自己做错了什么,但我无法弄清楚如何在不泄漏WKScriptMessage.body
中包含的任何值的情况下使用WKScriptMessageHandler
。
我已经尝试创建了一个最简化的Mac项目来隔离这个问题,但是没有任何效果。
在主视图控制器中:
class ViewController: NSViewController {
var webView: WKWebView?
override func viewDidLoad() {
super.viewDidLoad()
let userContentController = WKUserContentController()
userContentController.addScriptMessageHandler(self, name: "handler")
let configuration = WKWebViewConfiguration()
configuration.userContentController = userContentController
webView = WKWebView(frame: CGRectZero, configuration: configuration)
view.addSubview(webView!)
let path = NSBundle.mainBundle().pathForResource("index", ofType: "html")
let url = NSURL(fileURLWithPath: path!)!
webView?.loadRequest(NSURLRequest(URL: url))
}
}
extension ViewController: WKScriptMessageHandler {
func userContentController(userContentController: WKUserContentController, didReceiveScriptMessage message: WKScriptMessage) {
print(message.body)
}
}
然后在 index.html
文件中:
<html>
<head></head>
<body>
<script type="text/javascript">
webkit.messageHandlers.handler.postMessage("Here's a random number for you: " + Math.random() * 10)
</script>
</body>
</html>
当我运行该项目并在Instruments中打开内存调试器时,我看到以下泄漏:
如果我添加了一个重新加载请求的按钮,并且这样做几十次,应用程序的内存占用量会持续增长,并在某个阈值之后崩溃。在这个最小示例中可能需要一段时间才能崩溃,但在我的应用程序中,我每秒收到几条消息,它少于10秒就会崩溃。
整个项目可以在此处下载。
有什么想法是怎么回事吗?
WKUserContentController
会保留已注册处理程序直到被删除,这是很重要的知识,但与消息正文的泄漏无关。这是个好答案,但是回答了另一个问题。 - bdash