So at the end of the last article, we talked about the implementation of the class realizeClassWithoutSwift, so what’s going on inside realizeClassWithoutSwift?

1. Debug code preparation

Download objC818 debuggable source code

2. RealizeClassWithoutSwift analysis

Also add if judgment code in this function, just look at the function to handle LGPerson implementation, easy debugging

The list of guess methods should be inmethodizeClassTo deal with

2.1. MethodizeClass analysis

2.1.1. PrepareMethodLists analysis

FixupMethodList analysis

selAdd to the list of methods

Sort by address

Add unsorted print and sorted print

After a series of processing prepareMethodLists, look at the list of RO methods

There is still no data, so methods have not been added to the class yet.

2.1.2 Introduction of classification

MethodizeClass method inside

What is RWE? See this article, how to get the RWE?

Global search for extAllocIfNeeded. There are several places where extAllocIfNeeded is used to assign values to RWE, such as:

  • attachCategories
  • demangledName
  • class_setVersion
  • addMethods_finish
  • class_addProtocol
  • _class_addProperty
  • objc_duplicateClass

So rWE must have some value.

Using the backward method to search the position of the attachCategories call globally:

  • attachToClass
  • load_categories_nolock

Global search for the location of the attachToClass call:

  • methodizeClass

previouslyfortrueCan be called in the judgment conditionattachToClassMethods.previouslyismethodizeClassThe parameters of the

static void methodizeClass(Class cls, Class previously)
Copy the code

Global search for methodizeClass call location:

  • realizeClassWithoutSwift

Previously is also an argument to realizeClassWithoutSwift Global search for the location of the realizeClassWithoutSwift call found previously is nil as an argument, so the above method will not be called. So long came:

Global search load_categories_NOLock

  • loadAllCategories
  • _read_images

To understand theattachCategoriesSo let’s seeattachCategoriesHow is it implemented internally

2.1.3. AttachCategories analysis

2.1.4. AttachLists algorithm

3. Load categories and classes together

There are four types of category and class collocation loading. Now let’s look at each of these four cases. The goal is to see if there is any classification data in ro after the main class is loaded. If there is classification data, it means that the classification load is likely to be completed before compilation.

3.1. Both categories and classes have load methods

_read_images Non-lazy loading class > realizeClassWithoutSwift>methodizeClass>attachToClass>load_categories_nolock>attachCategories>

3.2. The class has a load method, but the main class does not

Call order: _read_images non-lazy loaded class > realizeClassWithoutSwift > methodizeClass > attachToClass

Note: No attachCategories are called

3.3. The main class has a load method, but the class does not

Call order: _read_images non-lazy loaded class > realizeClassWithoutSwift > methodizeClass > attachToClass

Note: attachCategories are also not called

3.4. There is no load method for categories or classes

Nothing is called until the object sends the message for the first time.

3.5. Classification loading process tracking

3.5.1. There is only one category

A load method for both the main class and the classification is used as an example.

@interface LGPerson : NSObject
@property (nonatomic.copy) NSString *name;
- (void)personFunc;
@end

@implementation LGPerson
// Add or delete as necessary
+ (void)load{}
- (void)saySomething{
    NSLog(@"%s",__func__);
}
@end
Copy the code
@interface LGPerson (LGA)
@property (nonatomic.copy) NSString *cateA_name;
- (void)cateFunc;
@end

@implementation LGPerson (LGA)
// Add or delete as necessary
+ (void)load{}
- (void)cateFunc{
    NSLog(@"%s",__func__);
}
@end
Copy the code

inrealizeClassWithoutSwiftIn the

mlistThe address tomlistsIn the

3.5.2. There are multiple categories

Supplementary test code:

@interface LGPerson (LGB)
- (void)cateFuncB;
@end

@implementation LGPerson (LGB)
// Add or delete as necessary
+ (void)load{}
- (void)cateFuncB{
    NSLog(@"%s",__func__);
}
@end
Copy the code

Process tracking:

3.5.3. The class implements load. The main class does not implement load

dyldThe time has come together, existdata()inside

3.5.4. The main class implements LOAD, but the classification does not

dyldThe time has come together, existdata()inside

3.5.5. None has been implemented

None of the implementations defer initialization until the first message is sent, and their methods are already loaded into data.

4. The nature of classification

1. Add a category code in main.m

#import <Foundation/Foundation.h>
#import "LGPerson.h"
#import <objc/runtime.h>
@interface LGPerson (LG) <NSObject>
@property (nonatomic, copy) NSString *cate_name;
@property (nonatomic, assign) int cate_age;
- (void)cate_instanceMethod1;
- (void)cate_instanceMethod2;
+ (void)cate_classMethod3;
@end
@implementation LGPerson (LG)
- (void)cate_instanceMethod1{
    NSLog(@"%s",__func__);
}
- (void)cate_instanceMethod2{
    NSLog(@"%s",__func__);
}
+ (void)cate_classMethod3{
    NSLog(@"%s",__func__);
}
@end
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        LGPerson *p = [LGPerson alloc];
        [p cate_instanceMethod2];
        NSLog(@"Hello, World!");
    }
    return 0;
}
Copy the code

3. Compile main.m into a c++ file

clang -rewrite-objc main.m -o main.cpp
Copy the code

_category_tClassification structure structure

The list of methods is not theregetandsetMethod, so the classification to add attributes need to be implemented themselvesgetandsetMethod associated object

5. Loading lazy and non-lazy classes

Lazy loading: Whether the current class implements the load method

  • Non-lazily loaded classes inmap_imagesWhen loading all data:map_images>map_images_nolock> _read_images>readClass>_getObjc2ClassList >realizeClassWithoutSwift>methodizeClass
  • Lazy-loading class data loading is delayed until the first message execution:lookUpImpOrForward >initializeAndMaybeRelock>realizeClassMaybeSwiftMaybeRelock>realizeClassWithoutSwift>methodizeClass

6. Summary

  • Lazy loading: Whether the current class is implementedloadmethods
  • The classification method, like the class method, is derived frommachoRead in, if its implementationloadMethod is calledattachCategoriesAnd perform a series of calculations, soloadMethod time consuming.
  • Do not implementloadMethod, method will be indyldWhen loading and coexist intodata()In the