美文网首页
Runtime(二)

Runtime(二)

作者: 952625a28d0d | 来源:发表于2017-01-18 22:09 被阅读32次
  • OC 和 C的本质区别
    C语言在编译的时候我就知道你等下会调用哪一个函数
    OC在编译的时候,不知道不要调用哪一个函数(动态编译)

  • 消息发送机制

#import "ViewController.h"
#import "Person.h"
#import <objc/message.h>    // 默认导入Runtime

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    
    Person *p = [[Person alloc] init];
//    [p run];
    
    // 在Xcode5.0之后 苹果不建议使用底层函数
    // 发送一个消息给 p
    objc_msgSend(p,@selector(run));
    objc_msgSend(p, @selector(earWithFoot:),@"香蕉");
    
    // 调用类方法 Class类型也是一个特殊的对象
    Class personClass = [Person class];
    // 不管是对象还是类 都可以发送消息
    objc_msgSend(personClass, @selector(run));
}


- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}


@end
#import <Foundation/Foundation.h>

@interface Person : NSObject

+ (void)run;

- (void)run;

- (void)earWithFoot:(NSString *)foot;

@end
#import "Person.h"

@implementation Person

- (void)earWithFoot:(NSString *)foot{
    NSLog(@"吃%@",foot);
}

- (void)run{
    NSLog(@"跑起来了");
}

+ (void)run{
    NSLog(@"类方法");
}

@end```


- 测试

![Paste_Image.png](https://img.haomeiwen.com/i189984/211e905c33804fde.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)


###使用Runtime进行方法替换

  • (void)viewDidLoad {
    [super viewDidLoad];

    // 平时这么写 创建URL 但是有可能为空! 如果字符串有中文 那么发送请求就会出错 那么就会Crash 我们想不到Url为空。。
    NSURL *url = [NSURL URLWithString:@"www.baidu.com/中文"];
    NSLog(@"%@",url);

}```

Paste_Image.png
  • 使用Category+load实现方法交换

1:第一步 写个url Category

#import <Foundation/Foundation.h>

@interface NSObject (url)

+ (instancetype)JYF_URLWithString:(NSString *)URLString;

@end```


- 第二部分 进行方法交换


import "NSObject+url.h"

import <objc/runtime.h> // 使用Runtime进行方法的交换

@implementation NSObject (url)

// 只要加载这个类 只要参与了加载 就会调用load方法

  • (void)load{
    NSLog(@"%s",func);
    // 1:拿到两个方法 苹果原来的URLWithString和我们自己扩展的JYFURLWithString
    // 获取类方法 class_getClassMethod 实例方法 class_getInstanceMethod
    // 参数 1:类型 2:方法编号
    Method mURLWithStr = class_getClassMethod([NSURL class], @selector(URLWithString:));
    Method mHK_URLWithStr = class_getClassMethod([NSURL class], @selector(JYF_URLWithString:));

    // 2:交换这两个方法
    method_exchangeImplementations(mURLWithStr, mHK_URLWithStr);
    }

  • (instancetype)JYF_URLWithString:(NSString *)URLString{
    NSURL *url = [NSURL JYF_URLWithString:URLString]; // 会找URLWithString这个方法 跑出去了 然后找系统的方法去执行
    if (url == nil) {
    NSLog(@"哥们是个空的Url");
    }
    return url;
    }

@end


- 测试


![Paste_Image.png](https://img.haomeiwen.com/i189984/cbc6b83e627ccc84.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

- 方法替换成功!!!



- 降低消耗

###使用Runtime进行方法的懒加载:
那么方法的懒加载用过么?懵逼??
- 怎么去懒加载OC中的方法?

- 先加载一个没有的方法 直接报错后 我们在m文件中进行处理

  • (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

    Person *p = [[Person alloc] init];
    // 懒加载:用到的时候再加载方法!!
    [p performSelector:@selector(eat)];
    [p performSelector:@selector(eat:) withObject:@"板烧鸡腿堡"];
    }


import "Person.h"

import <objc/message.h>

@implementation Person

// C语言
// 所有的C语言函数都有这两个隐士参数!只要调用 系统都会传递进来!那个对象的那个方法
void eat(id self, SEL _cmd){
NSLog(@"调用了%@对象的%@方法",self,NSStringFromSelector(_cmd));
NSLog(@"哥们吃了");
}

void eat1(id self, SEL _cmd, id obj){
NSLog(@"哥们今晚吃五个%@", obj);
}

// 当这个类被外界调用了没有实现的方法!!!就会来到这里了!!!

  • (BOOL)resolveInstanceMethod:(SEL)sel{
    NSLog(@"您没有实现这个方法%@",NSStringFromSelector(sel));
    if (sel == @selector(eat)) {
    /*
    1 cls:类类型
    2 sel: 方法编号
    3 imp: 方法实现 传入函数指针!
    4 types: 函数类型 C字符串 (代码)void === "v" 需要动态判断 写法根据文档来写
    */
    class_addMethod([Person class], sel, (IMP)eat, "v@:");
    }else if (sel == @selector(eat:)){
    class_addMethod([Person class], sel, (IMP)eat1, "v@:");
    }

    return [super resolveInstanceMethod:sel];
    }

@end


- 运行之后
![Paste_Image.png](https://img.haomeiwen.com/i189984/06cb64bcf1cc20ae.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

相关文章

网友评论

      本文标题:Runtime(二)

      本文链接:https://www.haomeiwen.com/subject/elybbttx.html