要在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是全局的?
我的测试似乎表明它们是独立的变量,特定于不同的UIViewControllers的不同实例,但这看起来很糟糕.
每个实例如何aoAA
可能不同 - 它使用相同的全局句柄?
Objective-C的"关联对象"概念允许您将一个"目标"对象实例与一个"源"对象实例连接起来.它是一个单向关联,只有源知道目标:
objc_setAssociatedObject(source, key, target, ...)
该关联使用密钥来连接和区分任意数量的关联对象与一个源.密钥必须明显不同 - 但仅适用于一个源实例.
因为您必须同时提供密钥和源实例来检索关联对象,所以不必使用真正唯一的密钥.实现objc_***AssociatedObject
可以通过组合实例指针和密钥来形成进程唯一密钥.
因此,对于你的榜样,是的,无论是aoAA
和aoBB
将返回单个值按每个UIViewController
实例,即使keyA
并keyB
是全球性的.
为了绝对清楚,你就需要不同的密钥每个在给定的扩展名关联的对象.所以,aoAA
和aoBB
每个人都需要自己的钥匙,如图中的示例代码(以机智的指针keyA
和keyB
).但正如在问题中所要求的那样,无论使用多少个符合类的扩展,每个关联对象只有一个键是正确的.