Swift-Runtime

在OC中,因其动态性我们经常会用到Runtime相关的API,探索一下Runtime在Swift中的注意点

  • 对于纯Swift类来说,没有动态特性。方法和属性不加任何修饰符的情况下,这个时候其实已经不具备我们所谓的Runtime特性了,这和C++方法调度(V-Table调度) 是不谋而合的。
  • 对于纯Swift类,方法和属性添加@objc标识的情况下,当前我们可以通过Runtime API拿到,但是在我们的OC中是没法进行调度的。
  • 对于继承自NSObject的类,如果我们想要动态的获取当前的属性和方法,必须在其声明前添加@objc关键字。否则也是没有办法通过Runtime API 获取的。
  • 如果想使用OC的动态转发机制,必须同时加@objcdynamic关键字

获取方法列表和属性列表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
class Teacher: NSObject {
var age: Int = 0
@objc func teach() {
print("你好啊")
}
@objc dynamic func teac1() {
print("你好啊")
}
}

func traversalMethod() {
var methodCount: UInt32 = 0
let methodList = class_copyMethodList(Teacher.self, &methodCount)
for i in 0..<numericCast(methodCount) {
if let method = methodList?[i] {
let methodName = method_getName(method)
print("方法:\(methodName)")
} else {
print("未找到方法")
}
}
}

func traversalProperty() {
var propertyCount: UInt32 = 0
let propertyList = class_copyPropertyList(Teacher.self, &propertyCount)
for i in 0..<numericCast(propertyCount) {
if let property = propertyList?[i] {
let propertyName = property_getName(property)
print("属性:\(String(utf8String: propertyName) ?? "")")
} else {
print("未找到属性")
}
}
}

traversalMethod()
traversalProperty()