Swift:将对象实例名称转换为String以用作键

时间:2018-10-16 14:08:50

标签: swift

鉴于var varName = "varValue",Swift中是否可以在运行时将变量名转换为String?例如,在这种情况下,我会退回"varName"

我已经了解Mirror的用于Swift反射的API。这使我可以遍历给定类的属性,但是对于任何给定类,我想将其应用于self。我想用它为任何给定的对象自动生成字符串键(无论它属于哪个类)

extension UIView {
   var key: String {
      return "" //TODO: Convert self to varName as String
   }
}

// Usage
let customView = UIView()
customView.key // should be "customView"

2 个答案:

答案 0 :(得分:0)

我不确定您要在这里完成什么,但是我认为您可以使用#keyPath(propertyName)在Swift中将变量名转换为字符串,但这需要您将@objc添加到var中。

例如

class MyViewController : UIViewController {
    @objc var name: String = "John"
}

print(#keyPath(MyViewController.name))

在控制台中打印name

答案 1 :(得分:0)

更新

OP添加了此注释以阐明要求:

  

我需要两个UIView实例的“键”不同。我希望该键对于该特定实例每次都相同,即如果应用重新启动或视图实例被销毁并重新创建,则该键不应更改。我可以将此密钥用作缓存中的密钥。另一个用例是将其用作accessibilityIdentifier来帮助进行UITesting。

在这种情况下,我建议不要考虑使用“魔术”。只是显式地给您的视图实例一个标识符。您还可以完全重用UIViewtag之类的accessibilityIdentifier上的现有属性。如果这还不够或不够方便,请子类:

class IdentifiableView: UIView {
    public private(set) var identifier: String

    init(frame: CGRect, identifier: String) {
        self.identifier = identifier
        super.init(frame: frame)
        self.accessibilityIdentifier = identifier
    }

    init() {
        fatalError("Must use init(frame:identifier:)")
    }

    override init(frame: CGRect) {
        fatalError("Must use init(frame:identifier:)")
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("Must use init(frame:identifier:)")
    }
}

// Usage
let firstView = IdentifiableView(frame: .zero, identifier: "First View")
firstView.identifier
firstView.identifier

let otherView = IdentifiableView(frame: .zero, identifier: "Second View")
otherView.identifier
otherView.identifier

如果根据您的评论,您只是希望“对象返回一个不变的唯一键”,则可以简单地使用它们的内存地址:

extension UIView {
    var key: String {
        return "\(Unmanaged.passUnretained(self).toOpaque())"
    }
}

let firstView = UIView()
firstView.key // -> "0x00007fbc29d02f10"
firstView.key // -> "0x00007fbc29d02f10"

let otherView = UIView()
otherView.key // -> "0x00007fbc29d06920"
otherView.key // -> "0x00007fbc29d06920"

对于您创建的UIView的每个实例,这将返回一个不变的唯一值。