The introduction of
As we know, classes can be added to add methods to a class, and you can define a variable via @property, but only the declaration of getter and setter methods for that variable is generated, no implementation of the method, and no underlined member variables. So the implementation of getter and setter methods needs to be implemented ourselves. We use Runtime to add associatedobject to the class, calling the two Runtime functions objc_setAssociatedObject and objc_getAssociatedObject. With two or two functions, you can store data for variables defined in a class into a table of associated objects of the class. So how is it stored and evaluated?
Storage analysis
We analyze this with an objC4-781 source code
Objc_setAssociatedObject Low-level call
Setassocook.get () is a call to a function pointer that actually calls the function _base_objc_setAssociatedObject
_base_objc_setAssociatedObject calls the _object_set_associative_reference function
That is, objc_setAssociatedObject actually calls _object_set_associative_reference, so why have so many calls in between? First, it is convenient to carry out more Settings later, and second, it can be more flexible to call different Settings in multiple places.
_object_set_associative_reference analysis
DisguisedPtr<objc_object> disguised{(objc_object *)object};
Wrap objcet into oneDisguisedPtr
ObjcAssociation association{policy, value};
Store policypolicy
andvalue
The value is wrapped into oneObjcAssociation
The acquireValue function is the processing under different storage policies
- right
OBJC_ASSOCIATION_SETTER_RETAIN
forobjc_retain
;
AssociationsManager is an associated object management class
- in
The constructor
andThe destructor
Add a lock to preventMultithreaded repeat creation
As a result of theHashMap
Repeated operation of
AssociationsHashMap is a global HashMap table that stores associated objects
- 1.
AssociationsHasMap
The structure of theDisguisedPtr
For the key andObjcetAssociationMap
For the value ofKey/value pair
;- 2.
AssociationsHashMap
Is through theAssociationsManager
theget
Function created;- 3.
static Storage _mapStorage
To ensure theAssociationsHashMap
Is globally unique.
value
If it does, it goes through the functiontry_emplace
According to the assembleddisguised
Go to theA hashMap table
Insert into table;value
If not, pass the functionfind
According to the assembleddisguised
Go to theA hashMap table
, and then erase the original records from the table.
- If no BucketT is found, return an empty BucketT for external callers to set the new value.
- New value found for return external caller setting.
Associated object structure
AssociationsHashMap is a HashMap table using DisguisedPtr as key and ObjectAssociationMap as Value. Each class using the associated object is inserted into the HashMap. ObjectAssociationMap is a Map table whose key is const void* and whose value is ObjcetAssociation. Associated objects of instances of classes that use associated objects are stored in this Map table.
Set the value process summary
- To create a
AssociationsManager
Management class;
- Gets a unique global static
HashMap
;
- Check whether the inserted correlation value exists:
(1) Existence goes to step 4; (2) do not exist to go: 'associated object insert empty process';Copy the code
- Create an empty
ObjectAssociationMap
To fetch the key-value pair of the query;
- If you don’t have this
key
I just insert an empty oneBucketT
Go in, go back;
- tag
Object has an associated object
;
- With the current
Storage policy
andvalue
Make up aObjcAssociation
Replace the originalBucketT
The empty;
- Mark the
ObjectAssociationMap
For the first timefalse
.
The associated object inserts an empty process
- According to the
DisguisedPtr
findAssociationsHashMap
In theiterator
Iterating query;
- Clean iterators;
- In fact, if you insert empty is equivalent to clearing.
Value analysis
Objc_getAssociatedObject analysis
_object_get_associative_reference analysis
- create
AssociationsManager
And find globally uniqueAssociationsHashMap
;- According to the
Disguised
findAssociationsHashMap
The iteratoriterator
;- find
objcet
theObjectAssociationMap
;- According to the
key
To find ObjectAssociationMap
In thevalue
And return.
Summary of Value Selection Process
- 1. Create one
AssociationsManager
Management class;- 2. Get a unique global static
HashMap
;- 3. According to
DisguisedPtr
findAssociationsHashMap
In theiterator
Iterating query;- 4. If the iterated query is not the last, get
ObjectAssociationMap
(Storage policy and value);- Find 5.
ObjectAssociationMap
theIterated query
Gets a value modified by an attribute modifier;- 6. Return
_value
.
conclusion
From the analysis of the storage value of the associated object, it can be seen that the associated object actually maintains a two-layer hash Map table.