前言
对于OC来说可以动态获取类的属性、方法等信息,但是对于Swift来说能不能获取到呢,我们先来看个实验。
实验
首先定义个纯Swift类,没有继承NSObject。
class PersonModel {
var name = "张三";
var age = 18;
func printInfo() -> Void {
print("姓名:\(name)\n年龄:\(age)");
}
}
上边定义了简单的PersonModel类,没有继承任何类,那么我们通过runtime看看是否可以获取这个类的属性么。
测试案例:
let model = PersonModel();
var count: UInt32 = 0;
let cls = object_getClass(model);
let plist = class_copyPropertyList(cls, &count);
print("===开始获取");
for item in 0..<count {
let property = plist?[Int(item)]
let cname = property_getName(property!);
let name = String(cString: cname);
print("property:<\(name)>")
}
print("===结束获取");
下图是输出结果:

可以看到没有获取到任何属性。
那么我们就可以得出结论,纯Swift在runtime是没有办法获取类的属性的。那么获取类的方法呢,我们再看下面的测试。
代码接着测试:
print("===开始获取");
let methodList = class_copyMethodList(cls, &count);
for item in 0..<count {
let meth = methodList![Int(item)];
let m = method_getName(meth);
let mStrl = NSStringFromSelector(m);
print("方法:\(mStrl)");
}
print("===结束获取");
同样没有获取任何函数, 纯swift在runtime运行的时候是没有办法获取函数的。
由此可以推论出,纯swift在runtime运行的时候是没有办法获取到类任何信息。也可以看出swift并不支持动态获取信息。
那么我们就真的没有办法获取类的属性了么?我们知道swift是可以和OC混合开发的,也就是swift也支持OC,但是OC确实动态语言,所以swift也会不会继承OC的特性呢。我们赶紧测试一下。
我们先改一下这个PersonModel类。让他继承NSObject类。如下:
class PersonModel : NSObject{
var name = "张三";
var age = 18;
func printInfo() -> Void {
print("姓名:\(name)\n年龄:\(age)");
}
}
我们在运行一边上边的测试案例;会发现一个并没有获取到自己定义的任何信息,现在是用swift 4.2版本测试的,这个因为swift 4.2版本已经把@objc 去掉了,继承NSObject的类不会再自动生成@objc 的特性了,需要我们手动添加,这个@objc 是干什么的呢,添加这个是表明改属性具有OC属性的特性。那么我们加上以后,会看到如下的输出:
这个输出结果看着是不是很像OC的方法。对,就是,加了@objc 就会默认生成OC的get、set方法。还有两个函数init、.cxx_destruct这两个函数,以后再说。先不用管。
通过以上测试我们可以看到,继承NSObject添加的@objc 我们才可以获取到类的属性和方法。
结论:
纯Swift是在编译的时候已经确定了要调用的方法,而不是在运行的时候确定,这个和C有点类似,所以我们是没有办法在运行时获取方法和属性的。
对于继承OC的swift,并且有@objc 特性,才会保留OC运行时的特性。我们才可以在运行时候获取他们的属性和方法。