Using the clang command, we can compile oc code into C++, and we can see that the classes are structures

xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc Person.m
Copy the code

See this blog post for details

ObjcMsgSender (id(method receiver),selector, argument 1, argument 2,…..)

The essence of an object is a structure

LGPerson *p = [[LGPerson alloc] init];
LGPerson *p = ((LGPerson *(*)(id, SEL))(void *)objc_msgSend)((id)objc_getClass("LGPerson"), sel_registerName("new"));
Copy the code

The essence of the method – sending messages

objc_msgSend ? Message ((void (*) (id, SEL)) (void *) objc_msgSend) (p (id), sel_registerName (” run “));

Void *)objc_msgSend)((id)p Message receiver

Sel_registerName (“run”) Method id — name

Imp function implementation pointer — sel -> IMP?

About the interpretation of class read this blog: www.jianshu.com/p/45fe90253…

[self class] and [super Class]

There’s a class Person that inherits from NSobject, and it has a subclass Student that prints [self class] and [super class]. What does that print look like? As a result,

[34213:6419974] self class:LGStudent [34213:6419974] self class:LGStudent [34213:6419974] Super Class :LGStudentCopy the code

Somewhat unexpectedly, to find out why, we converted the oc code into C++ code, CD to the current file directory, and entered the command

xcrun -sdk iphonesimulator clang -rewrite-objc LGStudent.m
Copy the code

Find where to call

static void _I_LGStudent_log(LGStudent * self, SEL _cmd) {
  ((Class (*)(id, SEL))(void *)objc_msgSend)((id)self, sel_registerName("class"));
  ((Class (*)(__rw_objc_super *, SEL))(void *)objc_msgSendSuper)((__rw_objc_super){(id)self, (id)class_getSuperclass(objc_getClass("LGStudent"))}, sel_registerName("class"));
}
Copy the code

As you can see [self class], objc_msgSend is called, and the first argument passed in is self, which is the recipient of the message, and the second argument is the method number. Because you’re calling an instance method, you look for a selector from the list of methods of the current class, or if it doesn’t find one, you look for the list of methods of the superclass. Struct objc_super * _Nonnull super, SEL _Nonnull op, struct objc_super * _Nonnull super, SEL _Nonnull op… The first argument, objc_super, is a structure.

struct objc_super {
 /// Specifies an instance of a class.
 __unsafe_unretained _Nonnull id receiver;
  __unsafe_unretained _Nonnull Class super_class;
 /* super_class is the first class to search */
};
Copy the code

The first argument is also self, which is the current student class, and the second argument should be the parent class Person. The whole process is as follows

1. Construct the structure of objc_super, where the first member variable receiver is LGStudent, the same as self. The second member variable superClass refers to class LGPerson, because Son's superClass is this LGPerson. 2. Call objc_msgSendSuper to pass this structure and sel of setName. The function is doing something like this: Start looking for the setName selector from the superClass method list pointed to by the objc_super structure, and then call that selector with objc_super->receiver, possibly using objc_msgSend as well. The first argument theReceiver is the objc_super->receiver, and the second argument is the selector found in the objc_super->superClass.Copy the code

Addendum: A question was asked in a recent interview, where is the argument passed by objc_msgSender (receiver,selector)? At that time, I suddenly asked meng, usually read the blog, or more hands-on practice, more thinking, pay attention to details, because we do technology, details do not understand, it is difficult to make the whole function particularly perfect. [zmodop setAge:@”meshare”andName:@”funlux”]; The conversion to C++ code looks like this.

((void (*)(id, SEL, NSString * _Nonnull, NSString * _Nonnull))(void *)objc_msgSend)((id)(zmodop.__forwarding->zmodop), sel_registerName("setAge:andName:"), (NSString *)&__NSConstantStringImpl__var_folders_jt_p_s4qkbn7tn3s430s0tdp0680000gn_T_main_ba0904_mi_1, (NSString *)&__NSConstantStringImpl__var_folders_jt_p_s4qkbn7tn3s430s0tdp0680000gn_T_main_ba0904_mi_2);
Copy the code
As you can see, the parameters are in the back.Copy the code

This article also write good: www.cnblogs.com/allanliu/p/…