1. How to explain the keyword self and super?

(1) Self

Whenever you’re writing a method implementation, you have access to an important hidden value, self. Conceptually, Self is a way to refer to “the object that received this message.” It’s apointer, just like the greeting value above, and can be used to call a method on the current receiving object.

(2) Related explanations of super in the official document:

There’s anotherimportant keyword available to you in Objective-C, called super. Sending a message to super is a way to call through to a method implementation defined by a superclass further up the inheritance chain. The most common use of super is when overriding a method.

The official Apple documentation makes it clear that self calls its own method, and super calls its parent method. That is, when self calls a method, it starts with its own method list, and if it doesn’t, it starts with its parent method list. It follows that a super call can be faster in some cases.

Note: Self and super make method calls in a different starting order, but the recipient of the message is the same, the current self; Let’s explore and verify:

2. Explore the difference between self calling method and super calling method?

@implementation JSPerson -(instanceType)init{self = [super init]; if (self) { NSLog(@"%@-%@",[self class],[super class]); } return self; Int main(int argc, const char * argv[]) {@autoreleasepool {// insert code here... JSPerson *person = [[JSPerson alloc] init]; } return 0; }Copy the code

To explore the underlying implementation, we can use the clang command to compile it into a.cpp file and execute it in the current jsperson.m file directory terminal: Clang -rewrite-objc jsperson. m -o jsperson. CPP generate C++ file jsperson. CPP

// @implementation JSPerson

static instancetype _I_JSPerson_init(JSPerson * self, SEL _cmd) {
    self = ((JSPerson *(*)(__rw_objc_super *, SEL))(void *)objc_msgSendSuper)((__rw_objc_super){(id)self, (id)class_getSuperclass(objc_getClass("JSPerson"))}, sel_registerName("init"));
    if (self) {
        NSLog((NSString *)&__NSConstantStringImpl__var_folders_q9_m967z0vn5js5qqnp7gbfdwq80000gn_T_JSPerson_7c19d1_mi_0,((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("JSPerson"))}, sel_registerName("class")));
    }
    return self;
}

Copy the code
((class (*)(id, SEL))(void *)objc_msgSend)((id) sel_registerName(“class”))

[super class] [super class] ((Class (*)(__rw_objc_super *, SEL))(void *)objc_msgSendSuper)((__rw_objc_super){(id)self, (id)class_getSuperclass(objc_getClass(“JSPerson”))}, sel_registerName(“class”)

Objc_msgSend (void /* id self, SEL op,... */) OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0); OBJC_EXPORT void objc_msgSendSuper(void /* struct objc_super *super, SEL op, ... */) OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0);Copy the code

Objc_super is an objc_super structure built by the compiler. Look at the source code for objc_super:

struct objc_super { /// Specifies an instance of a class. __unsafe_unretained _Nonnull id receiver; /// Specifies the particular superclass of the instance to message. #if ! defined(__cplusplus) && ! __OBJC2__ /* For compatibility with old objc-runtime.h header */ __unsafe_unretained _Nonnull Class class; #else __unsafe_unretained _Nonnull Class super_class; #endif /* super_class is the first class to search */ };Copy the code

As you can see, the objc_super structure has a member called “receiver” and “super_class.” Receiver stores the receiver of messages. And if we look at the C++ code for [super class], we see that the first argument to objc_msgSendSuper is (__rw_objc_super){(id)self, (id)class_getSuperclass(objc_getClass(“JSPerson”))}; (id)class_getSuperclass(objc_getClass(“JSPerson”))}; (id)class_getSuperclass(objc_getClass(“JSPerson”))}; The first argument of objc_msgSendSuper is a pointer to the super_class structure, and the first member variable receiver stores self, which was received from the outside. From the pointer access we know that the receiver of objc_msgSendSuper is also self

NSLog(@"%@-%@",[self class],[super class]) prints the result as: jsperson-Jsperson why does Apple implement such super logic? In iOS, method search is a process from subclass to superclass and then to the root class of NSObject. Using super, you can directly locate the method of the superclass and start the search, eliminating the search of subclassCopy the code