鉴于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"
答案 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。
在这种情况下,我建议不要考虑使用“魔术”。只是显式地给您的视图实例一个标识符。您还可以完全重用UIView
或tag
之类的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
的每个实例,这将返回一个不变的唯一值。