首先说一下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
网友评论