Próbowałem z sam sposób jak wspomniano. Działa to idealnie dla mnie. Kod który próbowałem znaczy
class CustomWKWebView : WKWebView {
deinit {
print("CustomWKWebView - dealloc")
}
}
class LeakAvoider : NSObject, WKScriptMessageHandler {
weak var delegate : WKScriptMessageHandler?
init(delegate:WKScriptMessageHandler) {
self.delegate = delegate
super.init()
}
func userContentController(userContentController: WKUserContentController,
didReceiveScriptMessage message: WKScriptMessage) {
self.delegate?.userContentController(
userContentController, didReceiveScriptMessage: message)
}
deinit {
print("LeakAvoider - dealloc")
}
}
class ChildViewController: UIViewController , WKScriptMessageHandler{
var webView = CustomWKWebView()
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
}
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(webView)
webView.frame = self.view.bounds;
}
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
let url = NSURL(string: "https://appleid.apple.com")
webView.loadRequest(NSURLRequest(URL:url!))
webView.configuration.userContentController.addScriptMessageHandler(
LeakAvoider(delegate: self), name: "dummy")
}
func userContentController(userContentController: WKUserContentController, didReceiveScriptMessage message: WKScriptMessage)
{
}
deinit {
print("ChaildViewController- dealloc")
webView.stopLoading()
webView.configuration.userContentController.removeScriptMessageHandlerForName("dummy")
}
}
class ViewController: UIViewController {
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
}
override func viewDidLoad() {
super.viewDidLoad()
}
deinit {
print("ViewController - dealloc")
}
}
Log po popping ViewController jest:
ViewController - dealloc
ChaildViewController- dealloc
LeakAvoider - dealloc
CustomWKWebView - dealloc
UPDATE
umieścić poniżej linii w funkcji Twojego WebViewViewController za viewWillDisappear.
webView.navigationDelegate = nil
webView.scrollView.delegate = nil
Próbowałem, ustawiając tych dwóch delegatów w moim kodzie i zaczął się zawiesza. Rozwiązano, umieszczając powyższe linie w widokuOdkrywanie obiektu ChildViewController.
Wow. Dzięki! Uderzyliśmy głową w to, czy możesz wyjaśnić, jak się dowiedziałeś? – shannoga
@shannoga wygląda jak 'WKWebView' przechowuje' __unsafe_unretained' wskaźnik do twojego delegata. Czasami w widoku sieci zwalnianym nie następuje natychmiastowe zwolnienie kontrolera, co powoduje awarię, gdy widok WWW próbuje powiadomić delegata o czymś. –