You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在跨类传递的WKWebView中正常触发didFinish导航回调?

WKWebView didFinish回调不触发的解决方案

我帮你找到了两个导致回调无法触发的核心问题,咱们一步步来修正:

问题分析

1. Second类实例被提前释放

在one类的viewDidLoad方法里,你创建的second是局部变量,当viewDidLoad执行完成后,这个实例会被ARC(自动引用计数)立刻回收。而WKWebView的navigationDelegate是弱引用,代理对象被释放后,WebView自然无法把导航事件通知给它。

2. 未正确绑定导航代理

你虽然让Second类遵守了WKNavigationDelegate协议,但从来没有把WebView的navigationDelegate指向当前的Second实例——WebView根本不知道要把回调发给谁。

修正后的代码

修改第一个ViewController类

把Second实例从局部变量改成类的属性,延长它的生命周期:

class OneViewController: UIViewController {
    var webView: WKWebView = WKWebView()
    // 用实例属性保存Second对象,避免被提前释放
    var secondHandler: SecondHandler?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        secondHandler = SecondHandler()
        secondHandler?.web = webView
        secondHandler?.test()
    }
}

修改Second处理类

添加导航代理的绑定,同时做安全的可选值处理:

class SecondHandler: NSObject, WKNavigationDelegate {
    var web: WKWebView? = nil {
        didSet {
            // 当WebView被赋值时,自动绑定导航代理
            web?.navigationDelegate = self
        }
    }
    
    func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
        print("Test")
    }
    
    func test() {
        guard let url = URL(string: "https://google.com") else { 
            print("Invalid URL")
            return 
        }
        web?.load(URLRequest(url: url))
    }
}

关键修正点说明

  • 把Second实例升级为ViewController的属性,确保它的生命周期和ViewController一致,不会被提前回收。
  • 在web属性的didSet方法中自动设置navigationDelegate = self,确保WebView和代理对象正确关联。
  • 加入guard let做安全判断,避免强制解包!可能导致的崩溃问题。

内容的提问来源于stack exchange,提问作者Sam H

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 07:57:37