美文网首页iOS 笔记
Swift4.0 用运行时访问类的属性

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

作者: Dayon | 来源:发表于2017-12-27 15:43 被阅读22次

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

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..<Int(count) {
            //根据下标 获取属性
            let a = list?[i]
            //获取属性的名称
            let cName = property_getName(a!)
            let n = String(utf8String:cName)
            print(cName)
            print(n as Any)
            print("hhh")
        }

        /*
        // - 使用 guard let 守护,依次判断每一项是否有值,
        // - 只要有一项为nil,就不在执行后续的代码
        for i in 0..<Int(count) {

            guard let pty = propertyList?[i],
                let cName: UnsafePointer<Int8>  = 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<count; i++) {
        //根据下标 获取属性
        objc_property_t property = propertyList[i];
         //获取属性的名称
        const char *ptyName = property_getName(property);
        //char 转 NSString数据类型
        NSString *pName = [NSString stringWithUTF8String:ptyName];
        NSLog(@"属性是:%@",pName)
    }
    free(propertyList);

相关文章

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

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

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

    谨以此记录Swfit4.0的学习过程 类的属性前面需要加上@objc关键词或者类前面加上@objcMembers ...

  • Unity API——Application类的详解(一):列举

    Application类位于UnityEngine下,用于访问应用程序在运行时的一些数据。这个类不包含实例属性和实...

  • Java基础 - 反射(一)

    反射是什么 在程序运行时候,获取某一个类的信息。反射的核心是JVM在运行时才动态加载类或调用方法/访问属性,它不需...

  • super和this关键字的区别

    1.访问父类的属性,但不能访问父类的private属性[案例]super.属性名; 2.访问父类的方法,不能访问父...

  • Java反射

    反射的核心是JVM在运行时才动态加载类或调用方法/访问属性,它不需要事先(编译期)知道运行对象是谁。重点:是运行时...

  • ActionScript3.0基础(一)

    访问控制属性: public:公有属性 private:私有类型的变量和方法只允许定义它们的类访问,其他类访问报错...

  • 面试

    KVC KVC可以通过key直接访问对象的属性,或者给对象的属性赋值(包括私有属性),这样可以在运行时动态的访问或...

  • static、final、static和final

    static 静态的修饰属性,静态属性和方法是属于该类的所有对象的,可以用类名.静态属性/方法名来访问。用stat...

  • python --property()函数定义属性

    通常我们用“类对象.属性”的方式访问类中定义的属性,其实这种做法是欠妥的,因为它破坏了类的封装原则。换句话说,正常...

网友评论

    本文标题:Swift4.0 用运行时访问类的属性

    本文链接:https://www.haomeiwen.com/subject/jyeugxtx.html