To have an associated object in Swift, you simply use a memory address as a handle, and then use the objc calls.
The usual example code you can google everywhere is:
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) }
}
}
this works fine,
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)")
}
But wait...
The handles, keyA and keyB, are global to the whole project.
When you use aoAA and aoBB in different UIViewController, how can it possibly be that aoAA and aoBB act as properties specific to that instance?
Surely there is only "one" aoAA everywhere in the project?
ie, aoAA is a global - just as the handle keyA is a global?
My testing seemed to show that they are independent variables, specific to different instances of different UIViewControllers, but that seems barmy.
How can each instance of aoAA
possibly be different - it's using the same global handle?
Objective-C's concept of "associated objects" lets you connect one "target" object instance with one "source" object instance. It's a unidirectional association where only the source knows the target:
objc_setAssociatedObject(source, key, target, ...)
The association uses a key to be able to connect and distinguish any number of associated objects with one source. The keys must obviously be different—but just for one source instance.
Because you have to provide both the key and the source instance to retrieve the associated object, it's not necessary to use really unique keys. The implementation of objc_***AssociatedObject
can form a process-unique key by combining the instance pointer and the key.
So for your example, yes, both aoAA
and aoBB
will return individual values per each UIViewController
instance, even though keyA
and keyB
are global.
To be absolutely clear, you do need different keys for each associated object in a given extension. So, aoAA
and aoBB
each need their own key, as shown in the example code (to wit, the pointers to keyA
and keyB
). But as is asked in the question it's correct have only one key for each associated object, no matter how many conforming classes the extension is used in.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With