IOS martial arts esoteric article summary
Writing in the front
The previous article covered the loading of classes and categories, so this article will cover the underlying principles of class extension and associated objects.
A possible secret Demo for this section
Class extension
Class extension Extension is also called an anonymous classification to add attributes and methods to the current class
There are two forms:
- Directly in the
.m
New class extension in file - Of the new class extension
.h
Documents (approvedcommand+N
New – >Objective-C File
– > selectExtension
)
The nature of class extension
Through the clang low-level compilation
-
Write a class extension
-
through
xcrun -sdk iphonesimulator clang -arch arm64 -rewrite-objc main.m -o main-arm64.cpp
Command to generate a CPP file, open the CPP file, and search for the ext_name attribute -
To view
TCJPerson
Class extension method, inThe build process
, the method is added directly tomethodlist
, as part of a class, i.eAdded directly to this class at compile time
inside
Explore through source code debugging
-
create
TCJPerson+TCJEXT.h
That is, an extension of the class and a declaration of two methods -
Implement both methods in tcjPerson.m
-
run
Objc4-818.2 -
Source code procedures, inreadClass
Stop and checkcj_ro
conclusion
Class extensions are part of the class at compile time
.It's compiled with the class
The expansion of the class
justThe statement
, depends on theThe current main class
, there is no.m
File, you can think of it as ah.
file
2. Associated objects
The realization of the underlying principle is mainly divided into two parts:
- through
objc_setAssociatedObject
Set the value process - through
objc_getAssociatedObject
Value of the process
Associated object – Set value process
In the classificationTCJA
Override attribute incate_name
theThe set and get
By means ofruntime
Attribute association method implementation
-
Run the program, breakpoint breaks at
main
In thecate_name
The assignment of -
Continue to run, break at the classification
setCate_name
In the method
The objc_setAssociatedObject method has four parameters, representing respectively:
- Parameter 1: The object to associate, that is, to whom to add the associated attribute
- Parameter 2: identifier for next lookup
- Parameter 3: value
- Parameter 4: policy for the attribute, i.e
Nonatomic, atomic, assign
Etc., as shown below
Enter theobjc_setAssociatedObject
Source code implementations of Apple’s design interfaces often add an intermediate layer — even if the underlying implementation logic changes, the external interface will not be affected
_object_set_associative_reference method
According to the source code, it is mainly divided into the following parts:
- 1: Create one
AssociationsManager
Management class - 2: get
The only
theGlobal static hash Map
:AssociationsHashMap
- 3: Check whether it is inserted
The associated value value
If there is a- 3.1: Existence go to Step 4
- 3.2: Do not exist to go:
Associated object - Insert empty process
- 4:
try_emplace
Method and create an emptyObjectAssociationMap
To fetch the key/value pair of the query: - 5: If this is not found
key
I just insert an empty oneBucketT
Go in and come backtrue
- 6:
setHasAssociatedObjects
methodsThe tag object has an associated object
Which placeisa
Pointer to thehas_assoc
Properties fortrue
- 7: Use the present
The policy and the value
Make up aObjcAssociation
Replace the originalBucketT
The empty - 8: Mark it
ObjectAssociationMap
For the first timefalse
AssociationsManager
- define
AssociationsManager
Type, equivalent to an automatic callAssociationsManager
Initializes the destructor of the- lock
lock
Does not mean thatThe only
Just for the sake ofAvoid multiple threads
In fact, you can define more than one outsideAssociationsManager manager;
the
- lock
- define
AssociationsHashMap
The type ofThe hash map
theThe only
Where can it be reflected?- through
_mapStorage.get()
generateThe hash map
, including_mapStorage
Is a static variable, soThe hash map
It’s always going to be a static variable, so it’s going to beThe only
.
- through
Debug view the current data structure
So far ourvalue
It has a value of zero, zeroCJ
If the incomingvalue
Is null and goes to local scopeelse
The process, known from the source code, is equivalent toRemove the associated
.
Try_emplace method
- There are two returns, both through
std::make_pair
Generate the corresponding key-value pairs - through
LookupBucketFor
methodsTo find the bucket
If themap
Already in theThere are
,Direct return
, includingmake_pai
The second argument to rbool
A value offalse
- if
Could not find
byInsertIntoBucket
insertmap
, includingmake_pair
The second argument tobool
A value oftrue
Enter theLookupBucketFor
Source code, there are two methods with the same name, the second of which belongs toOverloaded function
The difference from the first is that the second parameter does notconst
Modifier, known from debugging that the external call is the second overloaded function called, and the secondLookupBucketFor
Method, the internal implementation is to call the firstLookupBucketFor
methods
Breakpoint run totry_emplace
Fetch in methodsbucket
Part of theTheBucket = InsertIntoBucket(TheBucket, Key, std::forward<Ts>(Args)...) ;
Go ahead and viewrefs_result
Then enter theif (refs_result.second)
theif
Process, passsetHasAssociatedObjects
willnonpointerIsa
的has_assoc
Marked astrue
Go ahead and execute, executetry_emplace
Check before and afterrefs
.
ObjectAssociationMap (value, policy) is inserted into the empty bucket after the first try_emplace operation. The value can be verified by debugging.
Then printp result.second
To return totrue
At this point, the attribute andvalue
Associated with the
Conclusion:The set value of the associated object is somewhat similar tocache_t
In theinsert
Methods insertsel-imp
As shown in the figure below
Of the association propertymap
Structure is as follows
AssociationsManager can have multiple associationSManagers. You can obtain an AssociationsHashMap by using the AssociationsManagerLock.
whilemap
There are many associated objects inmap
The type isObjectAssociationMap
, includingkey
forDisguisedPtr<objc_object>
, e.g.TCJPerson
Will correspond to aObjectAssociationMap
.TCJStudent
Also the correspondingA ObjectAssociationMap
.
ObjectAssociationMap Hash table contains many key-value pairs. Key is of type const void *. _object_set_associative_reference(id object, const void *key, ID value, uintptr_t policy) Key is the string that we set when we associate the property, and value is of type ObjcasSociety.
Among themObjcAssociation
Is for packagingpolicy
andvalue
Class of.
Object insert empty flow: mainly local scopedelse
Process, in fact, this process can be colloquially understood as when the incomingvalue
fornil
When,Remove the associated
It is mainly divided into the following steps:
- 1, according to the
DisguisedPtr
findAssociationsHashMap
In theiterator
Iterated query - 2. Clean up iterators
- 3, in fact, if inserted vacant equivalent to clear
Associated object – Set value process
main
In the printperson.cate_name
The breakpoint comes to the overridden property in the classificationget
methods
Enter theobjc_getAssociatedObject
The source code to achieve
_object_get_associative_reference method
Through the source code, it is mainly divided into the following parts
- 1: Create one
AssociationsManager
Management class - 2: gets a unique global static hash
Map
:AssociationsHashMap
- 3: through
find
Methods according to theDisguisedPtr
findAssociationsHashMap
In theiterator
Iterated query - 4: If the iterator is not the last to fetch:
ObjectAssociationMap
(The policy and the value
) - 5:
find
Methods to findObjectAssociationMap
Gets an iterated query with an attribute modifiervalue
- 6: return
value
Enter thefind
Method: Search iteratively based on the associated objectAssociationsHashMap
, i.e.,buckets
Print to see
Find the bucket that matches the key with the buckets
-
find
Method before execution, printj
For the time of,value
fornil
-
find
Method after query, printj
For the time of,value
为CJ
AssociationsHashMap uniqueness verification
Verify that AssociationsHashMap is unique and that AssociationsManager is not unique
(1) to get rid ofAssociationsManager
In the lock
(2) in_object_set_associative_reference
Define it again in themanager
和 associations
③ Two results can be seen from the following figureassociation
Is the same address, verify its uniqueness
④ The purpose of locking AssociationsManager is to ensure object security and prevent conflicts.
conclusion
The associative object is basically a two-layer hash map, that is, access is two-layer, similar to a two-dimensional array.
The underlying invocation flow of the associated object is shown below
3. Related issues
① The difference between class extension and classification
Category category
Used specifically to add new methods to a class
Cannot add member attributes to a class
, added member attribute, also cannot fetch- Note: it can actually pass
runtime
Add attributes to the classification, i.eProperties associated
, the rewritesetter
,getter
methods
- Note: it can actually pass
- Classification using
@property
Define variables, only generate variablessetter
,getter
methodsThe statement
.Cannot generate method implementations and underlined member variables
The extension class extensions
- May be said to be
Special classification
, also known asAnonymous classification
- can
Add member attributes to the class
, butAre private variables
- can
Add a method to a class
Also,Is a private method
Write in the back
Study harmoniously without being impatient. I’m still me, a different color of fireworks.