欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Swift 4.2 动态获取一个类的属性,方法,和变量。

程序员文章站 2024-03-13 11:57:51
...

前言

对于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 4.2 动态获取一个类的属性,方法,和变量。

可以看到没有获取到任何属性。

那么我们就可以得出结论,纯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 4.2 动态获取一个类的属性,方法,和变量。

同样没有获取任何函数, 纯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属性的特性。那么我们加上以后,会看到如下的输出:

Swift 4.2 动态获取一个类的属性,方法,和变量。

 这个输出结果看着是不是很像OC的方法。对,就是,加了@objc 就会默认生成OC的get、set方法。还有两个函数init、.cxx_destruct这两个函数,以后再说。先不用管。

通过以上测试我们可以看到,继承NSObject添加的@objc 我们才可以获取到类的属性和方法。

结论:

纯Swift是在编译的时候已经确定了要调用的方法,而不是在运行的时候确定,这个和C有点类似,所以我们是没有办法在运行时获取方法和属性的。

对于继承OC的swift,并且有@objc 特性,才会保留OC运行时的特性。我们才可以在运行时候获取他们的属性和方法。