Swift Runtime分析:还像OC Runtime一样吗?
Swift是苹果2014年发布的编程开发语言,可与Objective-C共同运行于Mac OS和iOS平台,用于搭建基于苹果平台的应用程序。Swift已经开源,目前最新版本为2.2。我们知道Objective-C是具有动态性的,能够通过runtime API调用和替换任意方法,那Swift也具有这些动态性吗? 分析用例 我们拿一个 方法、属性 动态性比较重要的一点就是能够拿到某个类所有的方法、属性,我们使用如下代码来打印方法和属性列表。? 对于纯Swift的TestASwiftClass来说任何方法、属性都未获取到。 对于TestSwiftVC来说除testReturnTuple、testReturnVoidWithaCharacter两个方法外,其他的都获取成功了。
这是为什么?
但为什么testReturnTuple?testReturnVoidWithaCharacter却又获取不到呢? 从Objective-c的runtime 特性可以知道,所有运行时方法都依赖TypeEncoding,也就是method_getTypeEncoding返回的结果,他指定了方法的参数类型以及在函数调用时参数入栈所要的内存空间,没有这个标识就无法动态的压入参数(比如testReturnVoidWithaId: Optional("v24@0:8@16") Optional("v"),表示此方法参数共需24个字节,返回值为void,第一个参数为id,第二个为selector,第三个为id),而Character和Tuple是Swift特有的,无法映射到OC的类型,更无法用OC的typeEncoding表示,也就没法通过runtime获取了。 Method Swizzling 动态性最常用的就是方法替换(Method Swizzling),将类的某个方法替换成自定义的方法,从而达到hook的作用。
Method Swizzling的代码如下
viewDidAppear 和testReturnVoidWithaId
F:testReturnVoidWithaId L:50 说明viewDidAppear已经被替换,但是testReturnVoidWithaId却没有被替换,这是为何? 我们在方法里打个断点看看,如图:? @objc用来做什么的?与动态性有关吗? @objc找到官方文档读读。 可以知道@objc是用来将Swift的API导出给Objective-C和Objective-C runtime使用的,如果你的类继承自Objective-c的类(如NSObject)将会自动被编译器插入@objc标识。 我们在把TestASwiftClass(纯Swift类)的方法、属性前都加个@objc 试试,如图:? dynamic文档里还有一句说明:? 而viewDidAppear是继承Objective-C类获得的方法,本身就被修饰为dynamic,所以能被动态替换。 我们把TestSwiftVC方法前加上dynamic再测一把,如图:? 从堆栈也可以看出,方法的调用前增加了@objc标识,testReturnVoidWithaId方法被替换成功了。 同样的做法,我们把TestASwiftClass的方法和属性也都加上dynamic修饰,做Method Swizzling,同样获得成功,如图? Objective-C获取Swift runtime信息 在Objective-c代码里使用 可以看到Swift中的TestSwiftVC类在OC中的类名已经变成 所以要想从Objective-c中获取Swift类的runtime信息得这样写: Objective-C替换Swift函数 给TestSwiftVC和TestASwiftClass的testReturnVoidWithaId函数加上dynamic修饰,然后我们在Objective-C代码里替换为testReturnVoidWithaIdImp函数: F:void testReturnVoidWithaIdImp(__strong id,SEL,__strong id) L:20 self=<TestSwift.TestSwiftVC: 0x7fb4e1d148f0> 说明两者的方法在加上dynamic修饰后,均能在Objective-c里被替换。(TestSwiftVC的testReturnVoidWithaId不加dynamic也会打印日志,为什么?留给读者思考) 总结
关于本文
MTT是手机淘宝技术团队(Mobile Taobao Tech team)的英文缩写,欢迎关注手机淘宝技术团队,一起交流分享无线技术,共创移动开发无限未来!扫描微信二维码关注我们!我们将分享更多的独家技术细节! (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |