美文网首页ios开发
Objective-C 「RunTime运行时」

Objective-C 「RunTime运行时」

作者: LuisX | 来源:发表于2016-06-23 11:34 被阅读69次
Objective-C

RunTime简称运行时。就是系统在运行的时候的一些机制,其中最主要的是消息机制。
RunTime是一套比较底层的纯C语言API,属于1个C语言库,包含了很多底层的C语言API。
在我们平时编写的OC代码中,程序运行过程时,其实最终都是转成了runtime的C语言代码。

XCode7使用Runtime:
objc_msgSend()报错Too many arguments to function call ,expected 0,have3

解决方案: 关闭msg检查机制

关闭msg检查机制

一、发送消息

本质:
方法调用的本质,就是让对象发送消息。
方法:
objc_msgSend(id self, SEL op, ...)

Flower.h文件中

#import <Foundation/Foundation.h>

@interface Flower : NSObject
- (void)showName;
- (void)showOtherName:(NSString *)otherName;
+ (void)showPrice;
+ (void)showOtherPrice:(NSString *)otherPrice;
@end

Flower.m文件中

#import "Flower.h"

@implementation Flower

- (void)showName{
    NSLog(@"LuisX");
}

- (void)showOtherName:(NSString *)otherName{
    NSLog(@"%@", otherName);
}

+ (void)showPrice{
    NSLog(@"100");
}

+ (void)showOtherPrice:(NSString *)otherPrice{
    NSLog(@"%@", otherPrice);
}

@end

RuntimeViewController.m文件中(消息机制应用):

#pragma     //////////消息机制//////////
#import "RuntimeViewController.h"
#import "Flower.h"
#import <objc/message.h>          //必须导入

@interface RuntimeViewController ()

@end

@implementation RuntimeViewController

- (void)viewDidLoad {
  
    [super viewDidLoad];
   Flower *flower = [Flower new];
  
    //////////调用实例方法//////////
    [flower showName];
    [flower showOtherName:@"FX"];
    //本质(使用RunTime):对象发送消息
    objc_msgSend(flower, @selector(showName));
    objc_msgSend(flower, @selector(showOtherName:), @"FX");
    //输出:   LuisX
    //输出:   FX
    //输出:   LuisX
    //输出:   FX
    
    //////////调用类方法//////////
    [Flower showPrice];
    [Flower showOtherPrice:@"200"];
    //本质(使用RunTime):类发送消息
    objc_msgSend([Flower class], @selector(showPrice));
    objc_msgSend([Flower class], @selector(showOtherPrice:), @"200");
    //输出:   100
    //输出:   200
    //输出:   100
    //输出:   200
  
} 
@end

二、方法交换

场景:
系统自带的方法功能不够,保持原有的功能给系统自带的方法扩展一些功能。
方法:
​class_getClassMethod(__unsafe_unretained Class cls, SEL name)
​method_exchangeImplementations(Method m1, Method m2)
说明:
​Ivar : 成员变量 如果要是动态创建/修改/查看属性,可以使用Ivar。
Method : 成员方法 如果要是动态创建/修改/查看方法,可以使用Method。
拓展阅读:
RunTime Method

RuntimeViewController.m文件中(方法交换应用):

#pragma     //////////方法交换//////////
#import "RuntimeViewController.h"
#import <objc/message.h>          //必须导入

@interface RuntimeViewController ()

@end

@implementation RuntimeViewController

- (void)viewDidLoad {
  
    [super viewDidLoad];
    //////////调用imageNamed方法//////////
    UIImage *image = [UIImage imageNamed:@"1.jpg"];
    //输出: 图片为空
  
}

@end

@implementation UIImage (FXImage)

/**
 *  加载分类到内存时调用
 *
 *  1.获取imageWithName方法地址
 *  2.获取imageWithName方法地址
 *  3.交换方法地址,相当于交换实现方式
 *
 */
+ (void)load{
    
    Method imageWithName = class_getClassMethod(self, @selector(imageWithName:));
    Method imageName = class_getClassMethod(self, @selector(imageNamed:));
    method_exchangeImplementations(imageWithName, imageName);
    
}

/**
 *  自定义imageWithName方法
 *
 *  1.既能加载图片,又能打印
 *  2.此时调用imageWithName相当于调用imageName(二者已经交换)
 *
 *  注意:不能在分类中重写系统方法imageNamed,因为会把系统的功能给覆盖掉,而且分类中不能调用super.
 */
+ (instancetype)imageWithName:(NSString *)name{
    
    UIImage *image = [self imageWithName:name];
    if (image == nil) {
        NSLog(@"图片为空");
    }
    return image;
    
}

@end

未完待续...

相关文章

网友评论

    本文标题:Objective-C 「RunTime运行时」

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