swift 方法交换

341 阅读1分钟

swift中没有dispatch_once。代替使用static let, 是线程安全性质的,

swift中想要某个代码只执行一次

private static let takeOnce: Void = {

//代码块。。。。

}()

swift中想要再load 和initialize 阶段搞事情。改怎么办??>

思路: UIApplication有一个next属性。它会在applicationDidFinishLanching之前被调用,通过runtime获取到所有类的列表,然后向所有遵循SelfAware协议的类发送消息

extension UIApplication {

private static let runOnce: Void = {

        SwizzlingTool.searchAndExecuteAwake()

    }()

    override open var next: UIResponder? {

        UIApplication.runOnce

        return super.next

    }

protocol SelfAware: AnyObject {

    static func awake()

    static func swizzlingForClass(_ forClass: AnyClass, originalSelector: Selector, swizzledSelector: Selector)

}

extension SelfAware {

    static func swizzlingForClass(_ forClass: AnyClass, originalSelector: Selector, swizzledSelector: Selector) {

        let originalMethod = class_getInstanceMethod(forClass, originalSelector)

        let swizzledMethod = class_getInstanceMethod(forClass, swizzledSelector)

        guard originalMethod != nil && swizzledMethod != nil else {return}

        

        if class_addMethod(forClass, originalSelector, method_getImplementation(swizzledMethod!), method_getTypeEncoding(swizzledMethod!)) {

            class_replaceMethod(forClass, swizzledSelector, method_getImplementation(originalMethod!), method_getTypeEncoding(originalMethod!))

        } else {

            method_exchangeImplementations(originalMethod!, swizzledMethod!)

        }

    }

}

参考文章:https://www.codercto.com/a/39074.html