为了账号安全,请及时绑定邮箱和手机立即绑定

iOS学习笔记--RunTime的理解

标签:
iOS
RunTime的理解

runtime:运行时刻是指一个程序在运行(或者在被执行)的状态。也就是说,当你打开一个程序使它在电脑上运行的时候,那个程序就是处于运行时刻。在一些编程语言中,把某些可以重用的程序或者实例打包或者重建成为“运行库"。这些实例可以在它们运行的时候被连接或者被任何程序调用。

OC中runtime:是一套比较底层的纯C语言API, 属于1个C语言库, 包含了很多底层的C语言API。 在我们平时编写的OC代码, 在程序运行过程时, 都会转换成runtime的C语言代码。比如类转成了runtime库里面的结构体等数据类型,方法转成了runtime库里面的C语言函数,平时调方法都是转成了objc_msgSend函数(所以说OC有个消息发送机制)

RunTime学习路线

MyImg

RunTime的实际使用

要我说RunTime对于初学者或者刚入门者就是装逼用的,啥用没有,
runtime最常用的几个用法:
动态的为一个类添加/修改/删除 成员变量、方法
而这些很少在平常的Coding中运用上,所以我说中级以下开发者,拿这些装B就行了。

import : 成员变量、类、方法

class_copyIvarList : 获得某个类内部的所有成员变量

class_copyMethodList : 获得某个类内部的所有方法

class_getInstanceMethod : 获得某个具体的实例方法(对象方法,减号开头)

class_getClassMethod : 获得某个具体的类方法 (加号)

method_exchangeImplementations : 交换2个方法的实现

1.objc_setAssociatedObject(self, &FYObjProKey, hotelName, OBJC_ASSOCIATION_COPY);
self 是要给哪个对象添加 变量
&FYObjProKey 是对这个变量的标记,获得这个变量也是需要这个key值得
hotelName 是 这个 变量的值
OBJC_ASSOCIATION_COPY 这个 是添加变量的策略,和属性的copy类似 
一共有 5 个策略
OBJC_ASSOCIATION_ASSIGN;            //assign策略
OBJC_ASSOCIATION_COPY_NONATOMIC;    //copy,nonatomic策略
OBJC_ASSOCIATION_RETAIN_NONATOMIC;  // retain,nonatomic策略
OBJC_ASSOCIATION_RETAIN //retain策略
OBJC_ASSOCIATION_COPY  //copy策略
2.objc_getAssociatedObject(self, &FYObjProKey)
 通过 &FYObjProKey 这个标记 获得 新添加的变量
代码示例

先定义一个Car类

///.h文件
#import <Foundation/Foundation.h>

@interface Car : NSObject

@property (nonatomic, copy)NSString *name;

- (void)runRun;

- (void)stopStop;

- (void)guess;

@end

///.m文件

#import "Car.h"

@implementation Car

- (void)runRun
{
    NSLog(@"法拉利,跑跑跑");
}

- (void)stopStop
{
    NSLog(@"劳斯莱,停停停");
}

@end

在写Car类的分类

#import "Car.h"
#import <objc/runtime.h>
@interface Car (RunTime)

@property(nonatomic,copy) NSString *allTime;

@end

#import "Car+RunTime.h"

static NSString *key = @"key";///这里只是一个Key标示

@implementation Car (RunTime)

////动态为Category扩展加属性

////动态的为扩展添加实现方法
- (void)setAllTime:(NSString *)allTime
{
    objc_setAssociatedObject(self, &key, allTime, OBJC_ASSOCIATION_COPY_NONATOMIC);
}

-(NSString *)allTime
{
    return objc_getAssociatedObject(self,&key);
}

@end
使用方法
#import "ViewController.h"

#import <objc/runtime.h>

#import "Car+RunTime.h"

/*
 能动态为一个类添加/修改/删除 一个成员变量、一个方法

 */

@interface ViewController ()

@property (nonatomic, strong)Car *zuoDiHu;

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.zuoDiHu = [[Car alloc]init];
    self.zuoDiHu.name = @"法拉利";

    [self changeInstanceVolume];

    ////method_exchangeImplementations
    [self exchangeInstanceMethod];

    ////class_addMethod
    [self addMethodForInstance];
    [self.zuoDiHu guess];

    ////给Category添加属性
    ////先为扩展类声明需要添加的属性
    ///char runTime
    /// objc_getAssociatedObject///设置getter
    ///objc_setAssociatedObject///设置setter
    self.zuoDiHu.allTime = @"动态添加Category属性";
    NSLog(@"%@",self.zuoDiHu.allTime);

}
///动态的更改成员变量的值
- (void)changeInstanceVolume
{
    //① 动态获取Car类中的所有属性[当然包括私有]
    unsigned int count = 0;
    Ivar *ivar = class_copyIvarList([self.zuoDiHu class], &count);
    //②遍历属性找到对应name字段
    for (int i = 0; i < count; i ++) {
        Ivar var = ivar[i];
        const char *varName = ivar_getName(var);
        NSString *name = [NSString stringWithUTF8String:varName];
        //③修改对应的字段值成劳斯拉斯
        if ([name isEqualToString:@"_name"]) {
            object_setIvar(self.zuoDiHu, var, @"劳斯拉斯");
        }
    }
    NSLog(@"%@",self.zuoDiHu.name);
}

////交换对象的方法
- (void)exchangeInstanceMethod
{
    ///①获取实例对象要交换的方法
    Method method1 = class_getInstanceMethod([self.zuoDiHu  class], @selector(runRun));
    Method method2 = class_getInstanceMethod([self.zuoDiHu class], @selector(stopStop));
    ///②进行方法交换
    method_exchangeImplementations(method1, method2);

    [self.zuoDiHu runRun];
    [self.zuoDiHu stopStop];
}

///动态的给类添加方法
- (void)addMethodForInstance
{
///①动态给Car类中添加guess方法:
   class_addMethod([self.zuoDiHu class], @selector(guess), (IMP)guessAnswer, "v@:");

}

void guessAnswer(id self,SEL _cmd){
    NSLog(@"动态的给类添加方法");
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
}

@end
点击查看更多内容
1人点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
移动开发工程师
手记
粉丝
32
获赞与收藏
323

关注作者,订阅最新文章

阅读免费教程

感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消