Swift4.0 用运行时访问类的属性

类的属性前面需要加上@objc关键词或者类前面加上@objcMembers ,否则运行时访问不了类的属性

Swift4.0 用运行时访问类的属性_第1张图片
image.png

原因:在Swift 4中继承 NSObject 的 swift class 不再默认全部 bridge 到 OC,如果我们想要使用的话我们就需要在class前面加上@objcMembers 这么一个关键字。

引用: 在 swift 3 中除了手动添加 @objc 声明函数支持 OC 调用还有另外一种方式:继承 NSObject。class 继承了 NSObject 后,编译器就会默认给这个类中的所有函数都标记为 @objc ,支持 OC 调用。苹果在Swift 4 中苹果修改了自动添加 @objc 的逻辑:一个继承 NSObject 的 swift 类不再默认给所有函数添加 @objc。只在实现 OC 接口和重写 OC 方法时才自动给函数添加 @objc 标识。

import UIKit
//需要加上@objcMembers 这么一个关键字。
@objcMembers class Student: NSObject {
    var name :String?
    var age : Int = 18
    var title = "I like League of legend"
    var a:String?
    ///[使用运行时]获取当前类所有的属性数组
    class func propertyList() -> [String] {
        var count :UInt32 = 0
        //获取‘类’的属性列表
        let list = class_copyPropertyList(self, &count)
        print("属性的数量\(count)")
        for i in 0..  = property_getName(pty),
                let pName = String(utf8String: cName) else {

                //继续下一个
                continue
            }
            print(pName as Any)
        }
        */
        return [];
    }
}

注:之前用KVC赋值时就遇到过这个问题,原因同上;

KVC赋值

import UIKit

//在Swift 4中继承 NSObject 的 swift class 不再默认全部 bridge 到 OC,
//如果我们想要使用的话我们就需要在class前面加上@objcMembers 这么一个关键字。
@objcMembers class Person: NSObject {

    var name: String?
    var age: Int = 0
    var title: String?
    init(dict: [String: Any]) {
        super.init()
        setValuesForKeys(dict)
    }
}
import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
            
        print(Person.propertyList())
        
        let p = Person(dict: ["name" : "Any"])
        print(p.name as Any)
    }
}

OC 运行时访问类的属性:

    unsigned int count;
    objc_property_t *propertyList = class_copyPropertyList(self, &count);
    for (unsigned int i = 0; i

你可能感兴趣的:(Swift4.0 用运行时访问类的属性)