preface

In front of the class related knowledge, for these knowledge, combined with some comprehensive understanding of the interview questions, also can find some new things.

Related topics

1. When is the object associated with Asssociate released

Analysis:

  • inobjc4-812Source code, enterobjc_setAssociatedObjectCode implementation, found aobjc_removeAssociatedObjectsfunction
objc_removeAssociatedObjects

The source code is as follows

// Removes all associations for a given object.
objc_removeAssociatedObjects(**id** **_Nonnull** object)
    OBJC_AVAILABLE(10.6.3.1.9.0.1.0.2.0);
    
    
void objc_removeAssociatedObjects(id object) 
{
    if (object && object->hasAssociatedObjects()) {
        _object_remove_assocations(object, /*deallocating*/false); }}Copy the code
  • According to the comment at the definition of the function, what it does isRemove the associatedSearch globally, but find no other place to call, and then go look_object_remove_assocationsMethods:
_object_remove_assocations
void
_object_remove_assocations(id object, bool deallocating)
{
    ObjectAssociationMap refs{};
    {
        AssociationsManager manager;
        AssociationsHashMap &associations(manager.get());
        AssociationsHashMap::iterator i = associations.find((objc_object *)object);
        if(i ! = associations.end()) {
            refs.swap(i->second);

            // If we are not deallocating, then SYSTEM_OBJECT associations are preserved.
            bool didReInsert = false;
            if(! deallocating) { ... }... }}}Copy the code
  • The note says if notdeallocating, the association of the system is retained. fromobjc_removeAssociatedObjectsMethod in, passed indeallocatingParameters forfalse, indicating that it must not be this entry to disassociate. You can now locate which core is removed_object_remove_assocationsMethod, useBackstepping methodTo derive its invocation timing.
  • Go to search_object_remove_assocationsIt was found in theobjc_destructInstanceIs called in
objc_destructInstance

objc_destructInstanceThe implementation is as follows:

  • In the code found heredeallocatingfortrue“That means the place is right, and then searchobjc_destructInstanceIs calledobject_disposeMethod call
object_dispose



  • To search againobject_disposeWhere was it called and found in two placesrootDeallocCall theobject_dispose
rootDealloc

The two implementations are as follows:





  • But it has the same function name in both places. Search againrootDeallocThe call,
_objc_rootDealloc

RootDealloc is called in the _objc_rootDealloc method. Its source code is as follows

void
_objc_rootDealloc(id obj)
{
    ASSERT(obj);
    obj->rootDealloc(a); }Copy the code
dealloc

Finally, you search for _objc_rootDealloc, and you find dealloc

- (void)dealloc {
    _objc_rootDealloc(self);
}
Copy the code
  • That is to say, walk in the classDealloc will disassociate. Once the process is determined, look at the disassociation steps

dissociated

From the above analysis, we know the call_object_remove_assocationsMethod for disassociation:

  • From the code:
    • Let’s create an empty oneObjectAssociationMap.
    • To create aAssociationsManagerAnd then get the globalHashMapTable, then according toobjectFind a packObjectAssociationMapthebucket.
    • ifbucketNot the last one, which will be emptyObjectAssociationMapwithbucketIn theObjectAssociationMapStudent: Exchange ifdeallocatingforfalseThe traverseObjectAssociationMapIn thebucketIn theI ->second, insert the bucket that meets the conditionAnd willDidReInsert set to true.
    • And then determinedidReInsertforfalseWhen,AssociationsHashMapwillPerform clear associationoperationerase
    • And I’m going to create aSmallVector<ObjcAssociation *, 4>Type vector, used to storeObjcAssociation, and then iterateObjectAssociationMapIn thebucketWhen the conditions are met, go tolaterRefsaddObjcAssociationWhen the conditions are not metObjcAssociationexecute_valueThe release of
    • The traverselaterRefsIn theObjcAssociation, and then execute_valueRelease.

The flow chart

  • The process is as follows:



Conclusion:

After dealloc, the system disassociates.

2. +loadMethod invocation principles,loadandinitializeWhich calls first

  • loadSide of the call
    • loadMethod is indyldTo complete the call, is atmainFunction called before
    • loadThe order in which methods are called isThe parent class -> A subclass -> classification
    • Multiple classes and multiple classifications are called in the main compilation order, can be inbuild PhasesIn the adjustment
  • initializeMethod invocation
    • initializeinThe first message is sentIs called when. soloadbeforeinitializeThe call.
    • callinitialize, the parent class is called first, then the child class
  • C++The constructor
    • ifC++The constructor is written inobjcIn, the system will passstatic_init()Method is called directly, in this order:C++ -> +load -> main
    • If it is written inmainOr in your own code, the order of invocation is:+load -> C++ -> main

3. What is Runtime

    1. RuntimeIs made up ofC and C++ assemblyA set of implementationsApiforOCThe language adds object-oriented and runtime functionality
    1. RuntimeDeferring type determination from compile time to run time, such as the distinction between class extension and classification
    1. Write at ordinary timesOCThe code, while the program is running, will eventually turn intoRuntimetheCLanguage code, which isObjective-CBehind the scenes

4. What is the essence of method? What are SEL and IMP, and how are they related?

    1. The essence of the method is:Message is sent, the message has the following processes
    • Quick lookup:(objc_msgSend) ~ cache_tCache lookup
    • Slow to find: recursive | parent classlookUpImpOrForward
    • Not found: Dynamic method resolutionresolveInstanceMethod
    • Quick message forwarding:forwardingTargetForSelector
    • Slow forwarding of messages:methodSignatureForSelector & forwardInvocation
    1. selandIMP
    • selIs the method number ~ inread_imagesIt is compiled into memory
    • impThat’s our function implementation pointer, findimpIt’s finding the function
    • selIt’s like the table of contents of a booktittle 
    • impIt’s the page number of the book
    1. To look for specific functions is to look at specific chapters in the book:
    • We first know what we want to see, righttittleThat is(sel)
    • According to the table of contents to find the corresponding page number is(imp)
    • Turn to the detailsMethod implementation

5. Is it possible to add instance variables to the compiled class? Can you add instance variables to classes created at run time

    1. Can'tAdd an instance variable to the compiled class
    • Our compiled instance variable is stored atroOnce compiled, the memory structure is completely determined and cannot be modified
    • You can add methods and properties (associated objects) to classes by classification
    1. As long as the classNot registered to memory(Not implementedobjc_registerClassPairOperation) isYou can add.



6.[self class]and[super class]And how it works

Define a WSPerson class, then define a WSTeacher class that inherits from WSPerson, and print [self class] and [super class] in WSTeacher init method:



If we call WSTeacher alloc init in main, we’ll print WSTeacher, [self class] we know, but shouldn’t [super class] be WSPerson? Study their underbelly with questions.

  • First look at the source code for the class method:

    - (Class)class {
        return object_getClass(self);
    }
    
    Class object_getClass(id obj)
    {
        if (obj) return obj->getIsa(a);else return Nil;
    }
    Copy the code
    • Because the underlying message isobjc_msgSendAnd theobjc_msgSendThe first parameter ofMessage receiverThat is to sayclassHidden in the cordsselfisMessage receiver, it isWSTeacherAt this time,[self class]It’s easier to understand,selfisWSTeacherObject, andObject points to the class, so the final print resultWSTeacher.
    • butsuperIf it’s not a hidden parameter, the logic doesn’t work. So[super class]To see how:



    • Here comes aobjc_msgSendSuper2Function with the following header file:
    OBJC_EXPORT id _Nullable
    objc_msgSendSuper2(struct objc_super * _Nonnull super, SEL _Nonnull op, ...)
         OBJC_AVAILABLE(10.6.2.0.9.0.1.0.2.0);
    Copy the code
    • instructionssuperIt’s just a keyword. Look at the objc_super code:



  • Objc_super consists of two parameters: receiver and Class. Receiver is an instance of Class WSTeacher, so you end up with WSTeacher when you call the Class method.

7. Pointer translation problem

case

Let’s start with the following code:

WSPerson *person = [WSPerson alloc];
person.name = @"wushaung";
[person sayNB];

Class pClass = [WSPerson class];
void *ws = &pClass;
[(__bridge id)ws sayNB];
Copy the code
  • hereWSPersonThere is asayNBInstance method, firstpersonThe success of the invocation is beyond doubt, sowsIs the call successful?



  • The printout shows that both can be called successfully. Why?

Analysis of the

    1. First of all, the method is in the class,personIt can be called becausepersonIn theisaPointing to the class,personThe methods that can call a class are essentially the result of a pointer shift, sopersonYou can access methods in the class.
    1. void *ws = &pClass, the essence is willpClassAddress assigned towsPointer, at which pointwsIt also points to classes, which in turn allows access to methods.



The pressure of stack

  • Adjust the code below insayNBAdd to printnamePrint:
/ / print
- (void)sayNB {
    NSLog(Name: @ "🎈 🎈 🎈 % s % @", __func__, self.name);
}
Copy the code

The running results are as follows:

    • personThe value is actually by address0x8getnameValue:



    • That is, by the first address0x6000021d81b0translation0x8After getAddress of name: 0x6000021d81b8And then you get the valuewsAlso mimic the first address translation0x8:



    • And I just got itpersonSo the print result ispersonValue:



  • In WSPerson, add a hobby before name:

@interface WSPerson : NSObject

@property (nonatomic.retain) NSString *hobby;
@property (nonatomic.copy) NSString *name;

@end
Copy the code
  • At the moment to visitnameTo go throughhobbyProperty, which is to shift it0x10And print it again:



And now there isViewControllerHow is this, print the address analysis below:



  • At this timepClassAddress translation0x10After a0x00007ffee3052180Which is the ratiopersonThe address is still high, then only the currentViewDidLoadDelta function, we knowsuperThere is aobjc_superStructure whose members areThe receiver and the classAnd theViewDidLoadThere are two hidden parametersThe self and _cmd:



  • But the parameters of the structure stack is uncertain, so you can write a structure test
The structure stacks
  • Define a structure:



  • Then print each address below:



  • herepClasstranslation0x10after0x00007ffee4ce2170, justThe color address of cat, so print asblackAt this time,person, cat, pClassThe stack structure distribution is:



  • So you can explain the print in frontViewControllerThe reason is because of the access toClass information about the structure in super

Thus it can be seen that the structure of the stack direction is from the low address to the high address direction pressure

Arguments stack

Define a function:



  • Then run view print



This shows: the function parameters of the stack direction is from the high address to the bottom address direction pressure

To be continued…