【iOS runtime】iOS中函数的动态加载

本文深入探讨iOS中Objective-C动态加载的原理,特别是针对类目(Category)的动态加载过程。通过解析objc_method和objc_method_list结构体,展示了如何定义并添加自定义方法到现有类中。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

iOS runtime 函数的动态加载,以类目的加载为例。

ObjC中函数的动态加载很多地方都有涉及,其中最常见的就是类目(category)了,bundle loading里面有这样一句话:

The executable code files in loadable bundles hold class (and category) definitions that the NSBundle object can dynamically load while the application runs.

意思是:程序运行是能够动态的加载 bundles 持有类或者类目的定义。

研究动态加载的原理首先要 了解两个结构体:



1 类中每一个方法在内部转换后的结构体

struct objc_method 
{    
     SEL method_name; 函数名称 
     char *method_types; 函数类型
     IMP method_imp;  函数的具体实现 这里是一个指针,指向具体的实现
};
2 每一个类拥有的的函数列表
struct objc_method_list 
{  
    struct objc_method_list *obsolete; 函数列表 
    int method_count; 类中函数的个数 
    struct objc_method method_list[1]; 函数列表中的第一个函数地址
};


下面是函数具体的加载过程

0. 定义一个函数
1. 创建一个上面所说的objc_method结构体的实例,显然这个结构体的实例是一个函数,内部的参数由步骤0决定
   1.0 为结构体的函数名method_name赋值;
   1.1 为结构体的函数实现赋值。(函数指针指向(内存代码区)具体的实现)。
2. 添加objc_method结构体的实例到上面多说的第二个结构体 objc_method_list中
3. 调用class_addMethods方法,将objc_method_list添加到相应的类里面

下面代码示例:

#import <objc/objc-class.h>

// create a class with no methods
@interface EmptyClass : NSObject { }
@end

@implementation EmptyClass
@end

// define the function to add as a method
id sayHello ( id self, SEL _cmd,... )
{
  NSLog (@"Hello");
}

void addMethod ()
{
  struct objc_method myMethod; <span style="white-space:pre">				</span>//0 创建method实例
  myMethod.method_name = sel_registerName("sayHello"); <span style="white-space:pre">		</span>//1.0 为函数名赋值
  myMethod.method_imp  = sayHello; <span style="white-space:pre">				</span>//1.1 为函数实现赋值

  struct objc_method_list * myMethodList;
  myMethodList = malloc (sizeof(struct objc_method_list));
  myMethodList->method_count = 1;
  myMethodList->method_list[0] = myMethod;<span style="white-space:pre">		</span>//2 将自定义的函数实例添加到 list中
  
  class_addMethods ( [EmptyClass class], myMethodList );//3 将list绑定到类上面
  
  // 调用
  EmptyClass * instance = [[EmptyClass alloc] init];
  [instance sayHello];
  [instance release];
}
这基本就是OC动态加载的过程。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值