iOS开发 Runtime使用大全(一)

runtime,运行时。
就是说程序运行的时候可以进行操作,如调用新函数、删除已有的函数、改变变量的值等。

runtime就是实现语言动态的api
1.类的动态改变
2.消息传递
一个类的内部定义如下

struct objc_class {
    Class isa  OBJC_ISA_AVAILABILITY;
    #if !__OBJC2__
    Class super_class;//父类
    const char *name;//类名
    long version;//类的版本信息,默认为0
    long info;//类信息,供运行期使用的一些位标识
    long instance_size;//类的实例变量大小
    struct objc_ivar_list *ivars;// 类的成员变量链表
    struct objc_method_list **methodLists;// 方法链表
    struct objc_cache *cache;//方法缓存
    struct objc_protocol_list *protocols;//协议链表#
    endif} 

    OBJC2_UNAVAILABLE;

isa和super_class

isa:
每个实例对象都有一个isa指针,指向对象的类;
类也是一个对象,所以也有isa指针,指向元类。
元类也是对象,它的isa指针指向根元类

一个类方法被调用的时候,元类会去查自己是否有实现,没有就查父类,直到根类。

给OC对象发消息,runtime库会根据这个对象的isa指针其父类,然后在类方法列表里面寻找实现,若没有,就根据super_class寻找父类方法列表,直到根类。找到就运行这个方法

isa:实例对象-》类-》元类-》直接到根元类(NSObject的元类),根元类的isa指向自己
superclass:类-》父类-》中间类-》根类NSObject,袁元-》父元类》中间元类-》根元类-》根类;NSObject的superclass指向nil

SEL:类成员方法的指针,SEL只是保存了方法编号,不是方法的地址。
IMP:保存方法的地址
Method:方法结构体,保存方法名、实现和类型描述字符串

1.动态添加方法

//调用方法
[model performSelector:@selector(Wenwen)];
//自己重写的方法
- (void)addFind{
    NSLog(@"Wen Cheng");
}
//调用不存在的实例方法时调用
+ (BOOL)resolveInstanceMethod:(SEL)sel
{
    if ([NSStringFromSelector(sel) isEqualToString:@"Wenwen"]) {
        //这一行打断点
        return YES;
    }
    return NO;
}

如果直接运行,肯定会报错的。因为我们还没有添加方法。所以在运行成功后,再断点处,使用lldb命令,进行添加:call class_addMethod(self, sel, class_getMethodImplementation([HeaderModel class], @selector(addFind)), “v@:*”);
,就可以看到打印的”Wen Cheng”

未找到方法实现时,会调用以下几个方法。

//调用不存在的类方法时调用,默认NO,加入处理再返回YES
+ (BOOL)resolveClassMethod:(SEL)sel;
//处理实例方法
+ (BOOL)resolveInstanceMethod:(SEL)sel;
//调用其它类的方法,返回有这个方法的target
- (id)forwardingTargetForSelector:(SEL)aSelector;
//将不存在的方法打包成NSInvocation传给你
- (void)forwardInvocation:(NSInvocation *)anInvocation;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值