iOS_RunTime基础讲解

RunTime运行时是在iOS面试时经常会问到的问题,如果面试官问你有没有用到过RunTime运行时,你该怎么回到呢?
没用过?面试官会觉得你没有钻研底层代码的能力
用过?好吧,你是怎么用的?讲解一下你理解的RunTime

说到RunTime就不得不得说OC的消息机制,我们都知道OC是面向C的,它为C增添了许多面向对象的特性。而OC将很多静态语言在在编译和链接时做的事,交给一位幕后英雄就是RunTime。RunTime是一套纯C的API。

OC的函数调用就是消息发送,在真正运行的时候根据函数名称找到对应的函数来调用。

我们要知道OC的方法由哪几个部分构成呢?
1.SEL:方法编号
2.IMP:方法实现(注意其实它的本质不是函数体,而是函数指针)

我们可以这样理解,一个OC方法就是一本书,SEL方法编号就是这本书的目录标题,IMP方法实现就是对应的页码。而真正的函数体则是页码对应的正文。

消息机制原理就是:对象内部的isa指针根据SEL方法编号去映射表中查找对应的方法实现。

下面说一下简单的RunTime方法应用小例子:

我们创建一个Person类,在.h方法中注册一个eat方法,但是我们不去实现

#import <Foundation/Foundation.h>
@interface Person : NSObject
-(void)eat;
@end

在ViewController里面调用Person类的eat方法,此时会发生什么事?没错,程序会因为找不到方法的实现而崩溃。

#import "FirstViewController.h"
#import "Person.h"
@implementation FirstViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    Person * p =[[Person alloc]init];
    [p eat];
}

接下来我们在Person.m文件中,通过runtime消息转发,实例解析方法,来给Person动态添加eat方法的实现。

#import "Person.h"
#import <objc/runtime.h>//引用runtime头文件
@implementation Person
//消息转发
+(BOOL)resolveInstanceMethod:(SEL)sel{//解析实例方法
    //添加eat方法!
    class_addMethod(self, sel, eat, "");
    return [super resolveInstanceMethod:sel];
}
void eat(){
    NSLog(@"吃东西");
}
@end

此时,程序就能顺利输出NSLog了。

如果我们需要定义一个有参数的方法

#import <Foundation/Foundation.h>
@interface Person : NSObject
-(void)eatwithobjc:(NSString *)objc;
@end
#import "FirstViewController.h"
#import "Person.h"
@implementation FirstViewController
- (void)viewDidLoad {
    [super viewDidLoad];
    Person * p =[[Person alloc]init];
    [p eatwithobjc:@"汉堡!"];
}
#import "Person.h"
#import <objc/runtime.h>
@implementation Person
//消息转发
+(BOOL)resolveInstanceMethod:(SEL)sel{//解析实例方法
    //添加eat方法!
    class_addMethod(self, sel, eat, "");
    return [super resolveInstanceMethod:sel];
}
void eat(id self,SEL _cmd,NSString * objc){
    NSLog(@"吃东西!%@",objc);
}
@end

我们还需要添加隐藏参数id selfSEL _cmd

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值