如何在跨类传递的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
相关产品推荐
相关产品推荐

