Swift中的关联对象,全局键实际上是否会产生特定的实例?

时间:2017-01-24 12:13:48

标签: ios objective-c swift objective-c-runtime

要在Swift中拥有一个关联对象,只需使用内存地址作为句柄,然后使用objc调用。

您可以在任何地方使用google的常用示例代码是:

var keyA:UInt8 = 0
var keyB:UInt8 = 0
extension UIViewController {

    var aoAA: String? {
        get { return objc_getAssociatedObject(self, &keyA) as? String }
        set { objc_setAssociatedObject(self, &keyA, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN) }
    }
    var aoBB: String? {
        get { return objc_getAssociatedObject(self, &keyB) as? String }
        set { objc_setAssociatedObject(self, &keyB, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN) }
    }
}

这很好用,

class Thing: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        aoAA = "this is a"
        print("...... \(aoAA)")
        aoBB = "this is b"
        print("...... \(aoBB)")
        aoAA = "changed A"
        print("...... \(aoAA) \(aoBB)")
        aoBB = "changed B"
        print("...... \(aoAA) \(aoBB)")
        aoAA = aoBB
        print("...... \(aoAA) \(aoBB)")
        }

但等等......

句柄,keyA和keyB,是整个项目的全局

不同 UIViewController中使用aoAA和aoBB时,如何将aoAA和aoBB作为特定于该实例的属性?

当然只有"一个" aoAA在项目的每个地方?

即,aoAA是全局的 - 就像句柄keyA是全局的一样?

我的测试似乎表明他们独立变量,特定于不同UIViewControllers的不同实例,但这看起来很糟糕。

aoAA的每个实例如何可能不同 - 它使用相同的全局句柄?

1 个答案:

答案 0 :(得分:5)

Objective-C的“关联对象”概念允许您将一个“目标”对象实例与一个“源”对象实例连接起来。这是一个单向关联,只有源知道目标:

Associated Objects with source and target instances

objc_setAssociatedObject(source, key, target, ...)

该关联使用密钥来连接和区分任意数量的关联对象与一个源。键必须明显不同 - 但仅适用于一个源实例。

因为您必须同时提供密钥和源实例来检索关联对象,所以不必使用真正唯一的密钥。 objc_***AssociatedObject的实现可以通过组合实例指针和密钥来形成进程唯一密钥。

因此,对于您的示例,是的,aoAAaoBB都将为每个UIViewController实例返回单个值,即使keyAkeyB是全局的

为了绝对清楚, 需要不同的键,用于给定扩展中的每个关联对象。因此,aoAAaoBB都需要自己的密钥,如示例代码所示(即keyAkeyB的指针)。但正如在问题中所要求的那样,只要每个关联对象只有一个键,无论使用多少个符合类的扩展名。