关闭 NSWindow 后 WKWebView 没有回收

WKWebView is not reclaiming after closing the NSWindow

我在 NSWindowController 上给 window.close() 打过电话。我接到 window 控制器 deinit 电话。但是与 window 关联的 NSViewController 没有回收。未调用视图控制器的 deinit

window 控制器加载 WKWebView。然后我在调用关闭之前将 html 内容设置为空。我已经为 deinit 中的所有委托设置了 nil 并且委托都是弱的。

activity 监视器显示 Web Content 进程。

我有这样的代码:

class WebKitViewController: NSViewController {
    var webView: WKWebView?
    private lazy var msgService: WebViewMessageService? = {
        let s = WebViewMessageService()
        s.delegate = self
        return s
    }()
    weak var delegate: WebKitDelegate?
    // ...

    func initWebView() {
        let webView = WKWebView(frame: CGRect.zero, configuration: self.initWebKitConfig())
        webView.navigationDelegate = self
        webView.uiDelegate = self
        self.view.addSubview(webView)
        // ...
    }
}

如何使用基于WKWebViewNSWindowController回收内存并完全退出WindowController


WebKitViewController中的close函数如下

func closeWindow() {
    DispatchQueue.main.async {
        self.webView?.uiDelegate = nil
        self.webView?.navigationDelegate = nil
        self.msgService?.delegate = nil
        self.webView?.removeFromSuperview()
        if let window = self.view.window, let wc = window.windowController as? WebKitWindowController {
            Log.debug("Closing window \(wc.windowId)")
            self.webView?.loadHTMLString("", baseURL: nil)
            self.delegate?.closeWindow(windowId: wc.windowId)
        }
    }
}

这似乎是 WKScriptMessageHandler 的一个众所周知的错误。这是 link 提出的类似问题:

如何避免泄漏:

关闭 window 时调用 removeScriptMessageHandlerForName()