首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >WKWebView在deinit上崩溃

WKWebView在deinit上崩溃
EN

Stack Overflow用户
提问于 2016-02-20 21:11:28
回答 4查看 5.8K关注 0票数 15

我有这个等级- UIViewController -> ChildUIViewController -> WKWebView。

我对WKWebView消息处理程序有一个问题,它泄漏并阻止了子视图控制器的释放。

在阅读了一些之后,我找到了一种通过使用这个补丁- WKWebView导致我的视图控制器泄漏来修复保留周期的方法。

现在,我可以看到子视图控制器正在到达deinit,但在那之后,WKWebView就在deinit上崩溃了(Xcode中没有有用的日志)。

有什么想法或方向会有什么问题吗?

谢谢

更新这里是我的代码- 码基

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2016-06-02 08:51:07

将此放入子视图控制器的设计方法中。

代码语言:javascript
复制
webView.scrollView.delegate = nil
票数 12
EN

Stack Overflow用户

发布于 2017-02-08 08:18:32

不要忘记删除您添加的WKWebView的代表:

代码语言:javascript
复制
deinit {
    webView.navigationDelegate = nil
    webView.scrollView.delegate = nil
}

看起来WKWebView存储指向您的委托的__unsafe_unretained指针。有时,当web视图被释放时,视图控制器不立即被释放。当web视图试图通知委托某件事情时,这会导致崩溃。

票数 9
EN

Stack Overflow用户

发布于 2016-03-10 04:36:37

我试过的方式和你提到的一样。对我来说是完美的。我试过的密码是,

代码语言:javascript
复制
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")
    }
}

弹出ViewController后的日志如下:

代码语言:javascript
复制
ViewController - dealloc
ChaildViewController- dealloc
LeakAvoider - dealloc
CustomWKWebView - dealloc

更新

在WebViewViewController的viewWillDisappear函数中放置以下行。

代码语言:javascript
复制
    webView.navigationDelegate = nil
    webView.scrollView.delegate = nil

我尝试在我的代码中设置这两个委托,结果它开始崩溃。通过在viewWillDisappear of ChildViewController中放置上述行来解决问题。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35529080

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档