Runtime理解---方法调用和方法交换

Rruntime:

runtime底层方法调用,正常项目中OC 是不希望你去调用底层代码的,所以我们需要修改下配置文件(build settings 搜查msg 将bool修改为NO),之后创建一个Person类,并且创建一个eat方法
具体实现demo

  #import "Person.h"

@implementation Person
-(void)eat{
    NSLog(@"调用我了");
}
@end

利用 objc_msgSend调用eat方法

  Person *p = [[Person alloc] init];
  objc_msgSend(p, @selector(eat));

下面我们尝试不适用OC 上层代码调用具体代码如下

//创建对象
 NSObject* p = objc_msgSend(objc_msgSend(objc_getRequiredClass("Person"), @selector(alloc)), @selector(init));
 //调用方法
  objc_msgSend(p, @selector(eat));

验证是否是底层代码
1.创建一个command line Lauguage 选中OC
2.利用终端cd到main.c所在目录
3.执行clang -rewrite-objc main.m
4.找到main.cpp
如下是OC 底层实现代码

int main(int argc, const char * argv[]) {
    /* @autoreleasepool */ { __AtAutoreleasePool __autoreleasepool; 

        Person * p = ((Person *(*)(id, SEL))(void *)objc_msgSend)((id)((Person *(*)(id, SEL))(void *)objc_msgSend)((id)objc_getClass("Person"), sel_registerName("alloc")), sel_registerName("init"));
        NSLog((NSString *)&__NSConstantStringImpl__var_folders_7s_75jn6mvs2_xfh3v7hmq7v0140000gn_T_main_2edfc3_mi_0);
    }
    return 0;
}

方法交换

当项目中需要大的修改 或者某个方法有存在问题一般会用到
项目中如果url不符合规则就会url =nil,下面为URLWithString 添加一个筛选条件可以更清楚地定位到问题,为系统类的方法添加工程我们一般都会使用扩展类。添加NSURL+Url.H

NSURL * url = [NSURL URLWithString:@"中文"];

具体代码:

#import "NSURL+Url.h"
#import <objc/runtime.h>
@implementation NSURL (Url)
//+(instancetype)URLWithString:(NSString *)URLString{

//}
+(instancetype)YH_URLWithStr:(NSString *)str{
    NSURL *url = [NSURL YH_URLWithStr:str];
    if (url==nil) {
        NSLog(@"url为Nil");
    }
    return url;
}
+(void)load{
    //交换方法
    //method 成员方法
//    class_getClassMethod 获取类方法
//    class_getInstanceMethod 获取静态方法
    Method urlWithUrl = class_getClassMethod(self, @selector(URLWithString:));
    Method YH_URLWithStr = class_getClassMethod(self, @selector(YH_URLWithStr:));
    method_exchangeImplementations(urlWithUrl, YH_URLWithStr);

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值