iOS底层分析之类的扩展

229 阅读1分钟

和谐学习!不急不躁!!我是你们的老朋友小青龙~

类的拓展 - 认识

// main.m

/// 类的声明
@interface SSJPerson : NSObject
@property (nonatomic , strong) NSString *name;
@property (nonatomic , assign) NSInteger age;
-(void)runInstance;
+(void)runClass;
@end

/// 类的拓展
@interface SSJPerson ()
@property (nonatomic , strong)NSString *hoobby_extension;
@property (nonatomic , assign)float height_extension;
-(void)runInstance_extension;
+(void)runClass_extension;
@end

/// 类的实现
@implementation SSJPerson
// 本类方法
-(void)runInstance{}
+(void)runClass{}
// 拓展方法
-(void)runInstance_extension{}
+(void)runClass_extension{}
@end

int main(int argc, char * argv[]) {
    NSString * appDelegateClassName;
    @autoreleasepool {
        // Setup code that might create autoreleased objects goes here.
        appDelegateClassName = NSStringFromClass([AppDelegate class]);
    }
    return UIApplicationMain(argc, argv, nil, appDelegateClassName);
}

@end

然后在「终端」依次指向下面两条命令:

  • $cd main.m所在文件夹路径
  • $xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc main.m

这时候产生一个main.cpp文件:

image.png

image.png

通过.cpp文件我们发现,类拓展里的属性会加入到类的结构体里,类拓展里的方法也会加到类的_method_list_t里。

类的拓展 - 进一步探究

看到这里,我心中有所疑惑,不知道大家是否还记得之前文章讲到的分类知识点,分类里的属性、方法最终也会加载到类里面,那么类的扩展是否跟分类相似的?

带着这个问题,我们首先要定位,方法是什么时候加载到_method_list_t里的。根据前面几篇文章关于类的知识点,我们知道,类的初始化在realizeClassWithoutSwift函数,所以在这里下个断点:

image.png

为了能够更加快速定位、尽可能的减少干扰,我们在类的实现部分,添加一个load方法

// main.m文件

/// 类的实现
@implementation SSJPerson
...
+ (void)load{}
...
@end

运行工程:

image.png

image.png

总结:

  • 分类的数据,在读取data的时候就已经存在了。而data的数据是从mach-O里读取的。