Runtime在Swift中的用法

Runtime是什么?

  • 运行时(Runtime)是指将数据类型的确定由编译时推迟到了运行时
  • Runtime是一套比较底层的纯C语言API, 属于1个C语言库, 包含了很多底层的C语言API
  • 平时编写的OC代码,在程序运行过程中,其实最终会转换成Runtime的C语言代码,Runtime是Object-C的幕后工作者
  • Object-C需要Runtime来创建类和对象,进行消息发送和转发

Runtime的典型事例

  • 给系统分类添加属性、方法
  • 方法交换
  • 获取对象的属性、私有属性
  • 字典转换模型
  • KVC、KVO
  • 类的自我检测

Swift中如何使用runtime

Swift代码中已经没有了Objective-C的运行时消息机制, 在代码编译时即确定了其实际调用的方法. 所以纯粹的Swift类和对象没有办法使用runtime, 更不存在method swizzling. 
为了兼容Objective-C, 凡是继承NSObject的类都会保留其动态性, 依然遵循Objective-C的运行时消息机制, 因此可以通过runtime获取其属性和方法, 实现method swizzling.

代码实现:

extension UIViewController {
    public class func loadMethodSwizzing(){
        let originalSelector = #selector(UIViewController.viewDidAppear(_:))
        let swizzledSelector = #selector(UIViewController.myMethod(animated:))

        let originalMethod = class_getInstanceMethod(self, originalSelector)
        let swizzledMethod = class_getInstanceMethod(self, swizzledSelector)


        //在进行 Swizzling 的时候,需要用 class_addMethod 先进行判断一下原有类中是否有要替换方法的实现
        let didAddMethod: Bool = class_addMethod(self, originalSelector, method_getImplementation(swizzledMethod!), method_getTypeEncoding(swizzledMethod!))
        //如果 class_addMethod 返回 yes,说明当前类中没有要替换方法的实现,所以需要在父类中查找,这时候就用到 method_getImplemetation 去获取 class_getInstanceMethod 里面的方法实现,然后再进行 class_replaceMethod 来实现 Method Swizzing

        if didAddMethod {
            class_replaceMethod(self, swizzledSelector, method_getImplementation(originalMethod!), method_getTypeEncoding(originalMethod!))
        } else {
            method_exchangeImplementations(originalMethod!, swizzledMethod!)
        }

    }

    @objc func myMethod(animated: Bool) {
        self.myMethod(animated: animated)
        print("进入替换方法")
    }
}

在APPdategate中添加

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
      UIViewController.loadMethodSwizzing()
        return true
    }

参考blog:

Swift4.0中Runtime method_exchangeImplementations的使用和initialize()方法的替代

iOS --- 如何在Swift项目中使用runtime?

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值