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:
- in
objc4-812
Source code, enterobjc_setAssociatedObject
Code implementation, found aobjc_removeAssociatedObjects
function
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 is
Remove the associated
Search globally, but find no other place to call, and then go look_object_remove_assocations
Methods:
_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 not
deallocating
, the association of the system is retained. fromobjc_removeAssociatedObjects
Method in, passed indeallocating
Parameters forfalse
, indicating that it must not be this entry to disassociate. You can now locate which core is removed_object_remove_assocations
Method, useBackstepping method
To derive its invocation timing. - Go to search
_object_remove_assocations
It was found in theobjc_destructInstance
Is called in
objc_destructInstance
objc_destructInstance
The implementation is as follows:
- In the code found here
deallocating
fortrue
“That means the place is right, and then searchobjc_destructInstance
Is calledobject_dispose
Method call
object_dispose
- To search again
object_dispose
Where was it called and found in two placesrootDealloc
Call theobject_dispose
rootDealloc
The two implementations are as follows:
- But it has the same function name in both places. Search again
rootDealloc
The 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 class
Dealloc will disassociate
. Once the process is determined, look at the disassociation steps
dissociated
From the above analysis, we know the call_object_remove_assocations
Method for disassociation:
- From the code:
- Let’s create an empty one
ObjectAssociationMap
. - To create a
AssociationsManager
And then get the globalHashMap
Table, then according toobject
Find a packObjectAssociationMap
thebucket
. - if
bucket
Not the last one, which will be emptyObjectAssociationMap
withbucket
In theObjectAssociationMap
Student: Exchange ifdeallocating
forfalse
The traverseObjectAssociationMap
In thebucket
In theI ->second, insert the bucket that meets the condition
And willDidReInsert set to true
. - And then determine
didReInsert
forfalse
When,AssociationsHashMap
willPerform clear association
operationerase
- And I’m going to create a
SmallVector<ObjcAssociation *, 4>
Type vector, used to storeObjcAssociation
, and then iterateObjectAssociationMap
In thebucket
When the conditions are met, go tolaterRefs
addObjcAssociation
When the conditions are not metObjcAssociation
execute_value
The release of - The traverse
laterRefs
In theObjcAssociation
, and then execute_value
Release.
- Let’s create an empty one
The flow chart
- The process is as follows:
Conclusion:
After dealloc, the system disassociates.
2. +load
Method invocation principles,load
andinitialize
Which calls first
load
Side of the callload
Method is indyld
To complete the call, is atmain
Function called beforeload
The 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 in
build Phases
In the adjustment
initialize
Method invocationinitialize
inThe first message is sent
Is called when. soload
beforeinitialize
The call.- call
initialize
, the parent class is called first, then the child class
C++
The constructor- if
C++
The constructor is written inobjc
In, the system will passstatic_init()
Method is called directly, in this order:C++
->+load
->main
- If it is written in
main
Or in your own code, the order of invocation is:+load
->C++
->main
- if
3. What is Runtime
-
Runtime
Is made up ofC and C++ assembly
A set of implementationsApi
forOC
The language adds object-oriented and runtime functionality
-
Runtime
Deferring type determination from compile time to run time, such as the distinction between class extension and classification
-
- Write at ordinary times
OC
The code, while the program is running, will eventually turn intoRuntime
theC
Language code, which isObjective-C
Behind the scenes
- Write at ordinary times
4. What is the essence of method? What are SEL and IMP, and how are they related?
-
- The essence of the method is:
Message is sent
, the message has the following processes
- Quick lookup:
(objc_msgSend) ~ cache_t
Cache lookup - Slow to find: recursive | parent class
lookUpImpOrForward
- Not found: Dynamic method resolution
resolveInstanceMethod
- Quick message forwarding:
forwardingTargetForSelector
- Slow forwarding of messages:
methodSignatureForSelector & forwardInvocation
- The essence of the method is:
-
sel
andIMP
sel
Is the method number ~ inread_images
It is compiled into memoryimp
That’s our function implementation pointer, findimp
It’s finding the functionsel
It’s like the table of contents of a booktittle
imp
It’s the page number of the book
-
- To look for specific functions is to look at specific chapters in the book:
- We first know what we want to see, right
tittle
That is(sel)
- According to the table of contents to find the corresponding page number is
(imp)
- Turn to the details
Method implementation
5. Is it possible to add instance variables to the compiled class? Can you add instance variables to classes created at run time
-
Can't
Add an instance variable to the compiled class
- Our compiled instance variable is stored at
ro
Once compiled, the memory structure is completely determined and cannot be modified - You can add methods and properties (associated objects) to classes by classification
-
- As long as the class
Not registered to memory
(Not implementedobjc_registerClassPair
Operation) isYou can add
.
- As long as the class
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 is
objc_msgSend
And theobjc_msgSend
The first parameter ofMessage receiver
That is to sayclass
Hidden in the cordsself
isMessage receiver
, it isWSTeacher
At this time,[self class]
It’s easier to understand,self
isWSTeacher
Object, andObject points to the class
, so the final print resultWSTeacher
. - but
super
If it’s not a hidden parameter, the logic doesn’t work. So[super class]
To see how:
- Here comes a
objc_msgSendSuper2
Function 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
- instructions
super
It’s just a keyword. Look at the objc_super code:
- Because the underlying message is
-
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
- here
WSPerson
There is asayNB
Instance method, firstperson
The success of the invocation is beyond doubt, sows
Is the call successful?
- The printout shows that both can be called successfully. Why?
Analysis of the
-
- First of all, the method is in the class,
person
It can be called becauseperson
In theisa
Pointing to the class,person
The methods that can call a class are essentially the result of a pointer shift, soperson
You can access methods in the class.
- First of all, the method is in the class,
-
void *ws = &pClass
, the essence is willpClass
Address assigned tows
Pointer, at which pointws
It also points to classes, which in turn allows access to methods.
The pressure of stack
- Adjust the code below in
sayNB
Add to printname
Print:
/ / print
- (void)sayNB {
NSLog(Name: @ "🎈 🎈 🎈 % s % @", __func__, self.name);
}
Copy the code
The running results are as follows:
-
person
The value is actually by address0x8
getname
Value:
- That is, by the first address
0x6000021d81b0
translation0x8
After getAddress of name: 0x6000021d81b8
And then you get the valuews
Also mimic the first address translation0x8
:
- And I just got it
person
So the print result isperson
Value:
-
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 visit
name
To go throughhobby
Property, which is to shift it0x10
And print it again:
And now there isViewController
How is this, print the address analysis below:
- At this time
pClass
Address translation0x10
After a0x00007ffee3052180
Which is the ratioperson
The address is still high, then only the currentViewDidLoad
Delta function, we knowsuper
There is aobjc_super
Structure whose members areThe receiver and the class
And theViewDidLoad
There 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:
- here
pClass
translation0x10
after0x00007ffee4ce2170
, justThe color address of cat
, so print asblack
At this time,person, cat, pClass
The stack structure distribution is:
- So you can explain the print in front
ViewController
The 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