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.mNew class extension in file
  • Of the new class extension.hDocuments (approvedcommand+NNew – >Objective-C File– > selectExtension)

The nature of class extension

Through the clang low-level compilation

  • Write a class extension

  • throughxcrun -sdk iphonesimulator clang -arch arm64 -rewrite-objc main.m -o main-arm64.cppCommand to generate a CPP file, open the CPP file, and search for the ext_name attribute

  • To viewTCJPersonClass extension method, inThe build process, the method is added directly tomethodlist, as part of a class, i.eAdded directly to this class at compile timeinside

Explore through source code debugging

  • createTCJPerson+TCJEXT.hThat is, an extension of the class and a declaration of two methods

  • Implement both methods in tcjPerson.m

  • runObjc4-818.2 -Source code procedures, inreadClassStop and checkcj_ro

conclusion

  • Class extensions are part of the class at compile time.It's compiled with the class
  • The expansion of the classjustThe statement, depends on theThe current main class, there is no.mFile, you can think of it as ah.file

2. Associated objects

The realization of the underlying principle is mainly divided into two parts:

  • throughobjc_setAssociatedObjectSet the value process
  • throughobjc_getAssociatedObjectValue of the process

Associated object – Set value process

In the classificationTCJAOverride attribute incate_nametheThe set and getBy means ofruntimeAttribute association method implementation

  • Run the program, breakpoint breaks atmainIn thecate_nameThe assignment of

  • Continue to run, break at the classificationsetCate_nameIn 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.eNonatomic, atomic, assignEtc., as shown below

Enter theobjc_setAssociatedObjectSource 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 oneAssociationsManagerManagement class
  • 2: getThe onlytheGlobal static hash Map:AssociationsHashMap
  • 3: Check whether it is insertedThe associated value valueIf there is a
    • 3.1: Existence go to Step 4
    • 3.2: Do not exist to go:Associated object - Insert empty process
  • 4:try_emplaceMethod and create an emptyObjectAssociationMapTo fetch the key/value pair of the query:
  • 5: If this is not foundkeyI just insert an empty oneBucketTGo in and come backtrue
  • 6:setHasAssociatedObjectsmethodsThe tag object has an associated objectWhich placeisaPointer to thehas_assocProperties fortrue
  • 7: Use the presentThe policy and the valueMake up aObjcAssociationReplace the originalBucketT The empty
  • 8: Mark itObjectAssociationMapFor the first timefalse
AssociationsManager

  • defineAssociationsManagerType, equivalent to an automatic callAssociationsManagerInitializes the destructor of the
    • locklockDoes not mean thatThe onlyJust for the sake ofAvoid multiple threadsIn fact, you can define more than one outsideAssociationsManager manager;the
  • defineAssociationsHashMapThe type ofThe hash maptheThe onlyWhere can it be reflected?
    • through_mapStorage.get()generateThe hash map, including_mapStorageIs a static variable, soThe hash mapIt’s always going to be a static variable, so it’s going to beThe only.

Debug view the current data structure

So far ourvalueIt has a value of zero, zeroCJIf the incomingvalueIs null and goes to local scopeelseThe process, known from the source code, is equivalent toRemove the associated.

Try_emplace method

  • There are two returns, both throughstd::make_pairGenerate the corresponding key-value pairs
  • throughLookupBucketFormethodsTo find the bucketIf themapAlready in theThere are,Direct return, includingmake_paiThe second argument to rboolA value offalse
  • ifCould not findbyInsertIntoBucketinsertmap, includingmake_pairThe second argument toboolA value oftrue

Enter theLookupBucketForSource code, there are two methods with the same name, the second of which belongs toOverloaded functionThe difference from the first is that the second parameter does notconstModifier, known from debugging that the external call is the second overloaded function called, and the secondLookupBucketForMethod, the internal implementation is to call the firstLookupBucketFormethods

Breakpoint run totry_emplaceFetch in methodsbucketPart of theTheBucket = InsertIntoBucket(TheBucket, Key, std::forward<Ts>(Args)...) ;

Go ahead and viewrefs_result

Then enter theif (refs_result.second)theifProcess, passsetHasAssociatedObjectswillnonpointerIsahas_assocMarked astrue

Go ahead and execute, executetry_emplaceCheck 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.secondTo return totrueAt this point, the attribute andvalueAssociated with the

Conclusion:The set value of the associated object is somewhat similar tocache_tIn theinsertMethods insertsel-impAs shown in the figure below

Of the association propertymapStructure is as follows

AssociationsManager can have multiple associationSManagers. You can obtain an AssociationsHashMap by using the AssociationsManagerLock.

whilemapThere are many associated objects inmapThe type isObjectAssociationMap, includingkeyforDisguisedPtr<objc_object>, e.g.TCJPersonWill correspond to aObjectAssociationMap.TCJStudentAlso 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 themObjcAssociationIs for packagingpolicyandvalueClass of.

Object insert empty flow: mainly local scopedelseProcess, in fact, this process can be colloquially understood as when the incomingvaluefornilWhen,Remove the associatedIt is mainly divided into the following steps:

  • 1, according to theDisguisedPtrfindAssociationsHashMapIn theiteratorIterated query
  • 2. Clean up iterators
  • 3, in fact, if inserted vacant equivalent to clear

Associated object – Set value process

mainIn the printperson.cate_nameThe breakpoint comes to the overridden property in the classificationgetmethods

Enter theobjc_getAssociatedObjectThe source code to achieve

_object_get_associative_reference method

Through the source code, it is mainly divided into the following parts

  • 1: Create oneAssociationsManagerManagement class
  • 2: gets a unique global static hashMap:AssociationsHashMap
  • 3: throughfindMethods according to theDisguisedPtrfindAssociationsHashMapIn theiteratorIterated query
  • 4: If the iterator is not the last to fetch:ObjectAssociationMap (The policy and the value)
  • 5:findMethods to findObjectAssociationMapGets an iterated query with an attribute modifiervalue
  • 6: returnvalue

Enter thefindMethod: Search iteratively based on the associated objectAssociationsHashMap, i.e.,buckets

Print to see

Find the bucket that matches the key with the buckets

  • findMethod before execution, printjFor the time of,valuefornil

  • findMethod after query, printjFor the time of,valueCJ

AssociationsHashMap uniqueness verification

Verify that AssociationsHashMap is unique and that AssociationsManager is not unique

(1) to get rid ofAssociationsManagerIn the lock

(2) in_object_set_associative_referenceDefine it again in themanagerassociations

③ Two results can be seen from the following figureassociationIs 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 passruntimeAdd attributes to the classification, i.eProperties associated, the rewritesetter,gettermethods
  • Classification using@propertyDefine variables, only generate variablessetter,gettermethodsThe statement.Cannot generate method implementations and underlined member variables

The extension class extensions

  • May be said to beSpecial classification, also known asAnonymous classification
  • canAdd member attributes to the class, butAre private variables
  • canAdd a method to a classAlso,Is a private method

Write in the back

Study harmoniously without being impatient. I’m still me, a different color of fireworks.