runtime简单介绍

runtime: 称之为运行时,Xcode5开始,苹果建议使用runtime, runtimeOC的底层是实现,也就是说我们平时写的OC代码通过runtime形式都变成C语言代码去执行了。


例如:Person * p =[[Person alloc]init];最后转化成    Person * p = objc_msgSend([Person class], @selector(alloc), @selector(init)); -->最终转换成   Person * p = objc_msgSend(objc_msgSend(objc_getClass("Person"), sel_registerName("alloc")), sel_registerName("init"));


验证方法,Xcode创建工程MAC OS --> command line tool -->创建一个Personl -->main函数中创建一个person对象-->终端cdmain函数文件所在的文件目录 --> clang -rewrite-objc main.m --> main文件所在目录下面就会生成一个man.cpp文件,打开就会发现有一个段代码:

int main(int argc, const char * argv[]) {

    /* @autoreleasepool */ { __AtAutoreleasePool __autoreleasepool; 


        ((Person *(*)(id, SEL))(void *)objc_msgSend)((id)((Person *(*)(id, SEL))(void *)objc_msgSend)((id)objc_getClass("Person"), sel_registerName("alloc")), sel_registerName("init"));


    }

    return 0;

}

亦这就验证了上面的结论是正确的。


runtime的运用:

运用一:

利用runtime进行URLWithString的交换。

首先我们要清楚  一个类里面的方法load的调用是先与main函数和appdelegate里面的方法的。

load方法的解释:当这个文件被加载进来的时候就调用。

所以在自定义的NSURL分类的.m文件的load方法中进行操作:

+(void)load

{

    Method URLWithStr = class_getClassMethod([NSURL class], @selector(URLWithString:));

    Method AWURLWithStr = class_getClassMethod([NSURL class], @selector(AW_URLWithStr:));

    //方法的交换!!!!

    method_exchangeImplementations(URLWithStr, AWURLWithStr);

}


/如果你做了方法的交换!!一定记得!!注释!!

+(instancetype)AW_URLWithStr:(NSString *)str

{

    //想怎么实现就怎么实现!!!

    NSLog(@"来了");

    NSURL * url = [NSURL AW_URLWithStr:str];

    NSLog(@"come here");

    if(url == nil){

        NSLog(@"哥么这个urlnil");

    }

    return url;

}

这样当我们在别的类中调用系统的URLWithString这个方法的时候,就相当于调用了自己自定义的AW_URLWithStr方法



运用二:

方法的懒加载:

当一个类被调用了一个没有实现的对象方法,就会自动执行方法 +(BOOL)resolveInstanceMethod:(SEL)sel

例如:Person类没有定义OC写的对象方法eat:,那么当在ViewController中调用eat方法时候,就会自动调用resolveInstanceMethod方法。


ViewController.m文件中

Person * p = [Person new];

 [p performSelector:@selector(eat)];


Person.m文件中

//SEL 方法的一个编号!!

//发现这个类有一个实例方法没有实现!!

+(BOOL)resolveInstanceMethod:(SEL)sel{

    //来到这里..并且返回对应的SEL!!

    NSLog(@"%@",NSStringFromSelector(sel));

    //动态添加方法

    if (sel == @selector(eat)) {

        /**

         1.class

         2.SEL  方法编号

         3.IMP(Implementation)方法实现,其实它就是要你传入一个指针!!

         4.types 类型

         */

        class_addMethod([self class], sel,(IMP)eat, "v@:");

    }

    return [super resolveInstanceMethod:sel];

}


//隐式参数!! 1.方法所属的对象  2.方法的编号!     任何方法其实都有这两个隐式参数!

void eat(id obj, SEL _cmd){

    NSLog(@"哥么吃了!!%@",obj);

}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值