Swift中的关联对象,全局键是否实际产生具体实例?
Associated objects in Swift, does global key actually produce specific instances?
要在 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 怎么可能充当该实例的特定属性?
项目中肯定只有"one"个aoAA吗?
也就是说,aoAA 是全局的——就像句柄 keyA 是全局的一样?
我的测试似乎表明它们是 自变量,特定于不同 UIViewController 的不同实例,但这似乎很愚蠢。
aoAA
的每个实例怎么可能不同 - 它使用相同的全局句柄?
Objective-C 的 "associated objects" 概念允许您将一个 "target" 对象实例与一个 "source" 对象实例连接起来。这是一个单向关联,只有源知道目标:
objc_setAssociatedObject(source, key, target, ...)
关联使用一个键来连接和区分任意数量的关联对象与一个源。密钥显然必须不同——但仅适用于 一个 源实例。
因为您必须同时提供密钥和源实例才能检索关联的对象,所以没有必要使用真正唯一的密钥。 objc_***AssociatedObject
的实现可以将实例指针和key组合成process-uniquekey
因此,对于您的示例,是的,aoAA
和 aoBB
都会 return 每个 UIViewController
实例的单独值,即使 keyA
和 keyB
是全球性的。
为了绝对清楚,您 do 需要 different keys for each associated object in给定的扩展名。因此,aoAA
和 aoBB
每个都需要自己的密钥,如示例代码所示(即指向 keyA
和 keyB
的指针)。但是正如问题中所问的那样,无论有多少符合 类 扩展名,只有 one 键用于 each 关联对象是正确的用于.
要在 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 怎么可能充当该实例的特定属性?
项目中肯定只有"one"个aoAA吗?
也就是说,aoAA 是全局的——就像句柄 keyA 是全局的一样?
我的测试似乎表明它们是 自变量,特定于不同 UIViewController 的不同实例,但这似乎很愚蠢。
aoAA
的每个实例怎么可能不同 - 它使用相同的全局句柄?
Objective-C 的 "associated objects" 概念允许您将一个 "target" 对象实例与一个 "source" 对象实例连接起来。这是一个单向关联,只有源知道目标:
objc_setAssociatedObject(source, key, target, ...)
关联使用一个键来连接和区分任意数量的关联对象与一个源。密钥显然必须不同——但仅适用于 一个 源实例。
因为您必须同时提供密钥和源实例才能检索关联的对象,所以没有必要使用真正唯一的密钥。 objc_***AssociatedObject
的实现可以将实例指针和key组合成process-uniquekey
因此,对于您的示例,是的,aoAA
和 aoBB
都会 return 每个 UIViewController
实例的单独值,即使 keyA
和 keyB
是全球性的。
为了绝对清楚,您 do 需要 different keys for each associated object in给定的扩展名。因此,aoAA
和 aoBB
每个都需要自己的密钥,如示例代码所示(即指向 keyA
和 keyB
的指针)。但是正如问题中所问的那样,无论有多少符合 类 扩展名,只有 one 键用于 each 关联对象是正确的用于.