「这是我参与2022首次更文挑战的第10天,活动详情查看:2022首次更文挑战」。
- 本文主要介绍swift中如何使用
runtime
1. 回顾OC中runtime
-
什么是runtime 在OC中runtime本质是
底层的c,c++,汇编组成的API
。将我们编译时
确定的数据类型
推迟到运行时
确定,我们平时编写的OC的代码,需要用runtime
来创建
类和对象,进行消息发送
和转发
,最终都会转换为runtime
的c语言代码
。 -
为什么使用runtime?
- oc是一门
动态
语言,主要体现在以下3
个方面,因此需要运行时系统来处理编译后的代码
- 动态类型:运行时确定
对象的类型
- 动态绑定:运行时确定对象的
调用方法
- 动态加载:运行时加载需要的
资源或者可执行代码
- 动态类型:运行时确定
runtime
基本是用C语言和汇编语言写的,苹果和GNU
各自维护一个开源的runtime
版本,这两个版本之间都高度的保持一致
。
- runtime有什么用?
- 进行方法交换 (method swizzling)
- 给分类添加属性
- 动态的注册,创建一个类以及销毁
- 消息的发送和转发
- 访问私有变量
- 模型转数组
2. swift中runtime
我们定义一个swift类,并定义它的方法和属性,之后通过我们在oc中获取方法列表和属性列表
的方式打印
class Person {
var name = "jack"
func sleep() {
print("sleep")
}
}
do{
var methodCount:UInt32 = 0
let methodList = class_copyMethodList(Person.self, &methodCount)
for i in 0..<numericCast(methodCount){
if let method = methodList?[i] {
let methodName = method_getName(method)
print("methodName is \(methodName)")
}else{
print("not found method");
}
}
var properCount:UInt32 = 0
let proList = class_copyPropertyList(Person.self, &properCount)
for i in 0..<numericCast(properCount){
if let property = proList?[i] {
let propertyName = property_getName(property)
print("propertyName is \(propertyName)")
}else{
print("not found property");
}
}
}
最后什么也没打印,说明无法获取到,如果我们添加@objc
在属性和方法前面,是否就具备了运行时
的特性
就打印出来了,但是没有暴漏给oc
,所以oc
是无法使用的,这样做是没有意义的
没有任何关于Person
的信息
- 我们把类继续
NSObject
,并把@objc
去除
只有析构
方法,此时暴漏出来的只有init
方法,有.cxx_destruct
是因为我们的name
是String
类型一个对象。
我们换成常量的话就没有cxx_destruct
了
查看提供给oc的方法只有init
- 我们要提供给
oc
使用需要继承NSObject
,同时属性和方法使用@objc
修饰
- 我们把
@objec
换成dynamic
,还是不行
- 我们使用
@objc dynamic
进行修饰即可
3.结论
- swift是一门
静态
语言,而oc是动态
语言,所以纯swift类是不具有runtime
特性。是通过前面讲的方法调度:静态派发
和动态派发
。 - 对于
纯swift
类,我们使用@objc
修饰后的方法和属性具备了runtime
特性,但是我们的oc
中无法进行调度
,只能swift中
使用。 - 对于继承
NSObject
的swift
类,我们想要动态
的获取属性和方法需要在属性和方法前面修饰@objc
,否则也不具备runtime
特性。 - 对于
继承自NSObject
类来说,如果想要动态的获取当前属性+方法
,必须在其声明前
添加@objc
关键字,如果想要使用方法交换
,还必须在属性+方法前
添加dynamic
关键字,否则当前属性+方法只是暴露给OC
使用,而不具备任何动态特性 - 若方法的参数或者属性类型为
swift特有
的,无法映射
到oc
中的(比如Tuple
,Character
),则此方法的属性或者方法无法添加dynamic
修饰(编译器报错)