是否可以使用 swift.swizzle deinit。如果是,那么如何实现这一目标

ZaE*_*FaR 3 swizzling ios swift deinit

我想在我的项目中 UIViewController 的每个子类中的 deinit 中记录一些语句。我不想在每个视图控制器子类中复制/粘贴相同的行。

far*_*bfn 6

有一种方法可以实现这一点。

你不能 swizzle deinit,但你可以 swizzle 另一个方法,比如viewDidLoadassociatedObject. 当 viewController 释放时,关联对象也会被释放。

final class Deallocator {

    var closure: () -> Void

    init(_ closure: @escaping () -> Void) {
        self.closure = closure
    }

    deinit {
        closure()
    }
}

private var associatedObjectAddr = ""

extension UIViewController {

    @objc fileprivate func swizzled_viewDidLoad() {
        let deallocator = Deallocator { print("Deallocated") }
        objc_setAssociatedObject(self, &associatedObjectAddr, deallocator, .OBJC_ASSOCIATION_RETAIN)
        swizzled_viewDidLoad()
    }

    static let classInit: Void = {
        let originalSelector = #selector(viewDidLoad)
        let swizzledSelector = #selector(swizzled_viewDidLoad)
        let forClass: AnyClass = UIViewController.self
        let originalMethod = class_getInstanceMethod(forClass, originalSelector)
        let swizzledMethod = class_getInstanceMethod(forClass, swizzledSelector)
        method_exchangeImplementations(originalMethod!, swizzledMethod!)
    }()
}
Run Code Online (Sandbox Code Playgroud)

警告

封闭不会得到所谓的确切时的viewController被释放,因为在Deallocator被释放的viewController完全释放。