Swift 5 执行Runtime与OC之间的不同

首先说一下objectc是动态语言而swift是静态语言,而runtime又是基于动态语言的运行时进行的一些操作,所以就导致swift并不能像oc那样简单的使用runtime

一、关于类属性的名称、类型、运行时赋值和获取值。

class_copyIvarList 和 class_copyProperty 是获取当前类变量的方法

class_copyIvarList 可以获取全部的属性
class_copyProperty 只能获取@property的属性
以上两个方法在swift中都可以获取到全部属性包括私有属性但是不包括扩展里Associated设置的属性(目前我测试是这样的)

由于swift中很多类型都是值类型,比如NSString有了可替换的String,所以并不能动态编译。

在swift中定义String类型的属性 在使用object_getIvar和object_setIvar时候会导致bad access, 目前可替换的方法是让本类继承NSObject并且用@objc修饰定义的String,使用value(for:key)方法获取value;

至于Int可以 @objc dynamic var order_batch : Int = 0 初始化赋值的时候需要手动判空了,其他没有初始值的定义也可以参考Int样式定义

二、swift的extension和oc的category中不能定义属性但是可以使用runtime设置附加属性的set和get来达到定义属性的效果;

三、方法替换:使用class_getInstanceMethod获取到替换和被替换的方法实例,如果替换和被替换方法都已经存在已所属页面,那么直接用method_exchangeImplementations交换已经获取到的两个方法实例即可,若是需要用新方法替换需要class_addMethod先添加进runtime里,再替换class_replaceMethod;

        letAS =Selector(("aaa"))

        letBS =#selector(tihuanM)

        let AAA = class_getInstanceMethod(OrderList.self, AS)

        let BBB = class_getInstanceMethod(ViewController.self, BS)

        let didAddMethod = class_addMethod(OrderList.self, AS, method_getImplementation(BBB!), method_getTypeEncoding(BBB!))

        ifdidAddMethod

        {

            class_replaceMethod(ViewController.self, BS, method_getImplementation(AAA!), method_getTypeEncoding(AAA!))

        }

        else

        {

            method_exchangeImplementations(AAA!, BBB!)

        }

    @objc func tihuanM()    {        print("tttt")    }

如果不想写新方法 可以使用class_replaceMethod :imp_implementationWithBlock 直接把实现写在block里
四、总结一下runtime可以使用的范围 引用他人图片


截屏2020-04-1311.03.06.png

你可能感兴趣的:(Swift 5 执行Runtime与OC之间的不同)