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

iOS 10下NSKeyValueObservation在deinit阶段崩溃问题

解决iOS 10下WKWebView子类使用NSKeyValueObservation deinit崩溃问题

这个坑我之前踩过!核心原因是iOS 10中NSKeyValueObservation的自动失效机制存在局限性,尤其是WKWebView这类有特殊生命周期的子类,系统没法自动在对象释放前移除绑定的观察者,最终触发NSInternalInconsistencyException崩溃。

解决方案:手动接管观察者生命周期

iOS 11及以后,NSKeyValueObservation会自动在被观察对象销毁时失效,但iOS 10必须我们手动干预。具体操作如下:

  1. 把观察者实例存为类属性
    别在初始化方法里直接创建临时观察者,要把每个NSKeyValueObservation对象存为子类的私有属性,确保在deinit阶段能访问到它。

  2. 在deinit中显式调用invalidate()
    强制触发观察者失效,彻底解除它和当前对象的绑定,避免对象释放时还有残留的观察者注册信息。

完整代码示例

class WebView: WKWebView {
    // 每个监听对应一个属性,保存观察者实例
    private var contentOffsetObservation: NSKeyValueObservation?
    // 多个监听就添加多个属性
    // private var titleObservation: NSKeyValueObservation?
    
    override init(frame: CGRect, configuration: WKWebViewConfiguration) {
        super.init(frame: frame, configuration: configuration)
        setupObservers()
    }
    
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        setupObservers()
    }
    
    private func setupObservers() {
        // 创建观察者并绑定到属性
        contentOffsetObservation = observe(\.scrollView.contentOffset, options: [.new]) { [weak self] webView, change in
            // 监听逻辑里用weak self避免潜在循环引用
            guard let self = self else { return }
            print("Content offset changed: \(change.newValue ?? .zero)")
        }
        
        // 其他监听示例
        // titleObservation = observe(\.title, options: [.new]) { _, change in
        //     print("WebView title updated: \(change.newValue ?? "")")
        // }
    }
    
    deinit {
        // 手动失效所有观察者
        contentOffsetObservation?.invalidate()
        // titleObservation?.invalidate()
    }
}

额外注意事项

  • 闭包里一定要加[weak self],虽说NSKeyValueObservation本身不会造成循环引用,但能规避其他潜在的内存泄漏风险。
  • 多监听场景下,每个观察者都要单独存为属性并在deinit中失效,不能只处理其中一个。

这个方案既能解决iOS 10的崩溃问题,在iOS 11+上也能正常运行,完全兼容所有目标版本。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:01:21