要在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
的每个实例如何可能不同 - 它使用相同的全局句柄?
答案 0 :(得分:5)
Objective-C的“关联对象”概念允许您将一个“目标”对象实例与一个“源”对象实例连接起来。这是一个单向关联,只有源知道目标:
objc_setAssociatedObject(source, key, target, ...)
该关联使用密钥来连接和区分任意数量的关联对象与一个源。键必须明显不同 - 但仅适用于一个源实例。
因为您必须同时提供密钥和源实例来检索关联对象,所以不必使用真正唯一的密钥。 objc_***AssociatedObject
的实现可以通过组合实例指针和密钥来形成进程唯一密钥。
因此,对于您的示例,是的,aoAA
和aoBB
都将为每个UIViewController
实例返回单个值,即使keyA
和keyB
是全局的
为了绝对清楚, 需要不同的键,用于给定扩展中的每个关联对象。因此,aoAA
和aoBB
都需要自己的密钥,如示例代码所示(即keyA
和keyB
的指针)。但正如在问题中所要求的那样,只要每个关联对象只有一个键,无论使用多少个符合类的扩展名。