RunTime

作者: 莜12138 | 来源:发表于2017-03-06 16:22 被阅读34次

RunTime(运行时)是属于OC的一套底层实现,可以实现一些OC无法实现的底层操作。
当初学习RunTime的时候网上的资料也是琳琅满目,没一个看的懂得(我C语言功底比较差)。
下面我整理下自己的学习笔记,适合基础比较薄弱的同学学习

RunTime的常见操作:
<pre>
1.利用RunTime,在程序运行的过程中动态的创建一个类。
2.利用RunTime,在程序运行的过程中,动态的为某个类添加/修改 方法和属性。
3.遍历一个类的所有的成员变量和方法
</pre>
RunTime的用法:
<pre>
1.导入头文件<objc/runtime> <objc/message>
RunTime中的:
typedef struct objc_method *Method; 成员方法
typedef struct objc_ivar *Ivar; 成员属性

Ivar *class_copyIvarList      拷贝出一个对象的所有的成员变量列表 
Method *class_copyMethodList    拷贝出一个对象的所有的成员方法列表

Message中的:
objc_msgSend        给某个对象发送消息
objc_msgSendSuper     给某个对象的父类发送消息

</pre>

利用RunTime交换两个方法的实现
首先定义一个person类,在.h中声明两个方法并在.m中实现两个方法
<pre>

import <Foundation/Foundation.h>

@interface Person : NSObject
.h

  • (void)run;
  • (void)study;
    @end

.m

import "Person.h"

@implementation Person

  • (void)run
    {
    NSLog(@"跑");
    }
  • (void)study
    {
    NSLog(@"学习");
    }
    @end
    </pre>
    然后回到我们的ViewController中,引入需要用到的头文件
    <pre>

import "ViewController.h"

import "Person.h"

import <objc/runtime.h>

import <objc/message.h>

</pre>
<pre>/**
* 交换两个两个类的方法的实现
*/
// 第一次打印
[Person run];
[Person study];
// 拿到.h中的两个方法
Method m1 = class_getClassMethod([Person class], @selector(run));
Method m2 = class_getClassMethod([Person class], @selector(study));
method_exchangeImplementations(m1, m2);
NSLog(@"runtime交换后");
// 方法交换后打印
[Person run];
[Person study];
</pre>
![Uploading ECB8161F-58E0-4170-A8C2-E1F1F718CB51_146663.png . . .]
通过RunTime我们也可以拦截到系统的方法并重写系统方法
以UIImage的imageNamed:为例,我们首先为UIImage创建一个Category,并在.h中定义我们需要重写的方法
<pre>

import <UIKit/UIKit.h>

@interface UIImage (Category)
// 自定义一个方法,改变image的图片加载的系统方法,方法中写入要在系统方法中加入的语句(eg:版本判断)

  • (UIImage *)kk_imageNamed:(NSString *)name;
    @end
    </pre>
    <pre>#import "UIImage+Category.h"

import <objc/runtime.h>

@implementation UIImage (Category)

  • (UIImage *)kk_imageNamed:(NSString *)name
    {
    double version = [[UIDevice currentDevice].systemVersion doubleValue];
    if (version >= 7.0) {
    // 如果系统版本是7.0以上,使用另外一套文件名结尾是‘_OS7’的扁平化图片
    name = [name stringByAppendingString:@"_OS7"];
    }
    return [UIImage kk_imageNamed:name];
    }
  • (void)load
    {
    // 获取两个方法
    Method m1 = class_getClassMethod([UIImage class], @selector(imageNamed:));
    Method m2 = class_getClassMethod([UIImage class], @selector(kk_imageNamed:));
    // 交换两个方法的实现
    method_exchangeImplementations(m1, m2);
    }
    @end
    回到ViewController中
    /**
    • 重写系统的方法
      */
      UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(100, 100, 300, 100)];
      UIImage *image = [UIImage imageNamed:@"test"];
      imageView.image = image;
      [self.view addSubview:imageView];
      </pre>

相关文章

网友评论

    本文标题:RunTime

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