Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift:将对象实例名称转换为字符串以用作键_Swift - Fatal编程技术网

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

Swift:将对象实例名称转换为字符串以用作键,swift,Swift,给定var varName=“varValue”,Swift中是否有方法在运行时将变量名转换为String?例如,在本例中,我将返回“varName” 我已经知道了在Swift中反射的MirrorAPI。这允许我迭代给定类的属性,但我想将其应用于任何给定类的self。我想使用它为任何给定对象自动生成字符串键(不管它属于哪个类) 我不确定您试图在这里实现什么,但我认为您可以使用#keyPath(propertyName)将变量名转换为Swift中的字符串,但它需要您将@objc添加到您的变量中 比

给定
var varName=“varValue”
,Swift中是否有方法在运行时将变量名转换为
String
?例如,在本例中,我将返回
“varName”

我已经知道了在Swift中反射的
Mirror
API。这允许我迭代给定类的属性,但我想将其应用于任何给定类的
self
。我想使用它为任何给定对象自动生成字符串键(不管它属于哪个类)


我不确定您试图在这里实现什么,但我认为您可以使用
#keyPath(propertyName)
将变量名转换为Swift中的字符串,但它需要您将
@objc
添加到您的变量中

比如说

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

print(#keyPath(MyViewController.name))

在控制台中打印
name

更新

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
的每个实例,您创建的视图将返回一个不会更改的唯一值。

我不知道这是否可行,但我知道这不是您应该解决的方法。在运行时,您不应该关心变量名。
key
不是
func
@SanderSaelmans我愿意接受另一种建议,它允许我为问题中的用例提供唯一的常量键。我不在乎变量名。我关心给定数据库中的唯一密钥context@NumanTariq如果您只需要一个唯一的键,
UIView
有一个
tag
属性用于该确切目的。@JohannesFahrenkrug我不想手动分配唯一的键。我试图找到一种方法,让对象返回一个不变的唯一键。是的,但这不适合我在问题中指定的示例用例。理想的解决方案将根据问题中的用法工作。如果我理解正确,每个实例化的键都会改变?@NumanTariq。您说过“我试图找到一种方法让对象返回一个不变的唯一键。”该键自然就是它们在堆上的内存地址。
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"