【问题标题】:Listing all `dynamic` variables for a class in Swift2列出 Swift2 中类的所有“动态”变量
【发布时间】:2015-11-23 19:10:57
【问题描述】:

我正在编写一个实现KVO 的基类,我想推断该类的dynamic 属性的名称。例如:

class BaseClass {
  func beginObserving() {
    // What are the dynamic attributes to observe?
    // In the case of "SubClass" below, it should be ["name"]
    let attributes = ???
    for attribute in attributes {
      self.addObserver(self, forKeyPath: attribute, options: [.New, .Old], context: &KVOContext)
    }
  }
}

class SubClass : BaseClass {
  dynamic var name: String!
}

List of class's properties in swift 解释了如何使用Mirror(反射)来执行此操作,但它似乎不适用于dynamic vars(即,如果我删除了dynamic 关键字,则链接代码将适用于这种情况)。

【问题讨论】:

    标签: reflection swift2


    【解决方案1】:

    您可以使用标准的<objc/runtime.h> 函数:

    class MyObject {
        dynamic var identifier = 0
    
        func dynamicProperties() -> [String] {
            var dynamicProperties = [String]()
    
            var propertyCount = UInt32(0)
            let properties = class_copyPropertyList(object_getClass(self), &propertyCount)
            for var i = 0; i < Int(propertyCount); i++ {
                let property = properties[i]
                let propertyName = property_getName(property)
                dynamicProperties.append(String(CString: propertyName, encoding: NSUTF8StringEncoding)!)
            }
            free(properties)
    
            return dynamicProperties
        }
    }
    

    --

    如果您希望子类不仅显示其属性,还显示其超类的属性,您可以执行以下操作:

    class BaseClass {
        dynamic var identifier = 0
    
        func dynamicProperties() -> [String] {
            var dynamicProperties = [String]()
    
            var propertyCount = UInt32(0)
            let properties = class_copyPropertyList(object_getClass(self), &propertyCount)
            for var i = 0; i < Int(propertyCount); i++ {
                let property = properties[i]
                let propertyName = property_getName(property)
                dynamicProperties.append(String(CString: propertyName, encoding: NSUTF8StringEncoding)!)
            }
            free(properties)
    
            return dynamicProperties
        }
    }
    
    class SubClass : BaseClass {
        dynamic var name: String!
    
        override func dynamicProperties() -> [String] {
            var dynamicProperties = super.dynamicProperties()
    
            var propertyCount = UInt32(0)
            let properties = class_copyPropertyList(object_getClass(self), &propertyCount)
            for var i = 0; i < Int(propertyCount); i++ {
                let property = properties[i]
                let propertyName = property_getName(property)
                dynamicProperties.append(String(CString: propertyName, encoding: NSUTF8StringEncoding)!)
            }
            free(properties)
    
            return dynamicProperties
        }
    
    }
    

    【讨论】:

    • 这不起作用。对于具有动态属性 dynamic var name: String! 的子类,它返回 [],对于具有正常 let let x: UIntlet y: Uint 的子类,它返回 ["x", "y"]。即使您的示例案例也不输出 identifier 变量。您的代码与我在原始问题中链接的解决方案相同。
    • 不,它为具有dynamic var name: String! 动态属性的子类返回["name"]。它只返回该类的属性,而不是它的超类。如果您想要所有这些,则需要让子类将其属性附加到其超类的属性中,如修订后的答案所示。
    猜你喜欢
    • 2023-04-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-03
    • 2023-01-19
    • 2011-05-26
    • 1970-01-01
    • 2021-10-26
    相关资源
    最近更新 更多