Swift中的关联对象,全局键实际上是否生成特定的实例?
要在Swift中拥有关联对象,只需使用内存地址作为句柄,然后使用objc调用。
通常的示例代码,你可以谷歌无处不在:
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是一个全球性的?
我的testing似乎表明,它们是独立的variables,特定于不同的UIViewControllers的不同实例,但这似乎很糟糕。
aoAA
每个实例aoAA
可能不同 – 它使用相同的全局句柄?
Objective-C的“关联对象”概念允许您将一个“目标”对象实例与一个“源”对象实例连接起来。 这是一个单向的联系,只有来源知道目标:
objc_setAssociatedObject(source, key, target, ...)
该关联使用一个键能够连接和区分任何数量的关联对象与一个来源。 键必须明显不同 – 但只适用于一个源实例。
因为您必须提供密钥和源实例来检索关联的对象,所以没有必要使用真正唯一的密钥。 objc_***AssociatedObject
的实现可以通过组合实例指针和键来形成一个进程唯一键。
所以对于你的例子,是的,即使keyA
和keyB
是全局的, aoAA
和aoBB
都会为每个UIViewController
实例返回单独的值。
要清楚地说明,给定扩展中的每个关联对象都需要不同的键。 所以, aoAA
和aoBB
都需要自己的密钥,如示例代码所示(也就是keyA
和keyB
的指针)。 但正如在问题中所提到的那样, 每个关联对象只有一个关键字,不pipe这个关系使用了多less符合类。