runtime简单使用之动态添加方法

一, runtime的动态添加方法功能

  • 1, 关于runtime动态添加方法,我们以一个经典的面试题展开对其的研究.

  • 经典面试题 : 有没有使用过performSelector方法, 什么时候调用该方法?

    • 答 : 肯定是要回答使用过,不然就没有然后了........其实面试官主要是想问问你有没有动态添加过方法,下面我们就简单的学习runtime动态添加方法.
  • 2, 首先我们需要清除一个问题即: 为什么要动态添加方法,它的作用是什么,以及调用时刻是什么时候?

    答 : 在OC中,所有的控件(textFiled或者button等控件), 数组, 数据等都是以懒加载的形式加载的.真正使用的时候才会加载,或者添加方法.动态添加的方法的作用就是去处理未实现的实例方法或者是类方法.它的调用时刻: 只要我们调用了一个不存在的方法时,它就会动态添加方法.每个类都一个处理为实现方法的方法.

二, 步骤

  • 1, 新建一个学生类(WGStudent)在该类中只声明一个实例方法,不去实现,看看外界调用该方法时,会造成什么样的后果.

  • 下面这个方法是错误的演示


在 WGStudent.h文件中
#import <Foundation/Foundation.h>

@interface WGStudent : NSObject

// 如果该方法只有声明没有实现,那么该方法一定不会放在方法列表中,外界一定不能直接调用到方法
  - (void)study;

@end
在ViewController.h文件中
#import "ViewController.h"
#import "WGStudent.h"
#import <objc/message.h>

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    WGStudent *student = [[WGStudent alloc] init];

    objc_msgSend(student, @selector(study));

}
@end
  • 打印结果
// 根本找不到这个方法
reason: '-[WGStudent study]: unrecognized selector sent to instance 0x7f94bb46e070'
  • 2, 这时候就需要使用到runtime动态添加方法了.在动态添加方法之前我们还需要判断当前的方法有没有实现,如果没有实现才需要动态添加方法.所以, 我们就需要了解下面两个方法:
// 动态去判断下eat方法有没有实现,如果没有实现,动态添加.
// 作用:处理未实现的对象方法
// 调用时刻:只要调用了一个不存在的对象方法就会调用
// sel:就是未实现方法编号

// 判断对象方法有没有实现
+(BOOL)resolveInstanceMethod:(SEL)sel

// 判断类方法有没有实现
+ (BOOL)resolveClassMethod:(SEL)sel

  • 3, 进入苹果系统内部查看如何动态添加方法(这是官方文档中的方法)
// dynamicMethodIMP方法
// 动态添加这个dynamicMethodIMP方法
void dynamicMethodIMP(id self, SEL _cmd) {
    // implementation ....
}

// 苹果内部的动态添加方法
@implementation MyClass
+ (BOOL)resolveInstanceMethod:(SEL)aSEL
{
    if (aSEL == @selector(resolveThisMethodDynamically)) {
          class_addMethod([self class], aSEL, (IMP) dynamicMethodIMP, "v@:");
          return YES;
    }
    return [super resolveInstanceMethod:aSEL];
}
@end
  • 了解几个与动态添加方法有关的几个参数
// 参数解释:
        // Class;给哪个类添加方法
        // SEL:添加方法
        // IMP:方法实现,函数名
        // types:方法类型(不要去死记,官方文档中有)
class_addMethod(__unsafe_unretained Class cls, SEL name, IMP imp, const char *types)
  • 注意 : 动态添加方法的第三个参数是一个函数名,所以需要定义一个C语言函数,注意括号中的两个隐式参数,不能少,一下是给"学生类"动态添加方法,步骤都是按照苹果官方文档来创建的.
  • 2, 给学生动态添加一个学习英语的方法
在WGStudent.m文件中
// 模仿官方文档来动态添加方法
#import "WGStudent.h"
#import <objc/message.h>

@implementation WGStudent

void studyEngilsh(id self, SEL _cmd) {

    NSLog(@"动态添加了一个学习英语的方法");
}

+ (BOOL)resolveInstanceMethod:(SEL)sel {

    if (sel == NSSelectorFromString(@"studyEngilsh")) {
        // 注意:这里需要强转成IMP类型
        class_addMethod(self, sel, (IMP)studyEngilsh, "v@:");
        return YES;
    }
    // 先恢复, 不然会覆盖系统的方法
    return [super resolveInstanceMethod:sel];
}
@end

在ViewController.m文件中
#import "ViewController.h"
#import "WGStudent.h"
#import <objc/message.h>

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    WGStudent *student = [[WGStudent alloc] init];

    [student performSelector:@selector(studyEngilsh)];
}
@end
  • 打印结果
// 说明动态添加方法成功
2016-03-08 20:07:23.160 sasass[1280:35172] 动态添加了一个学习英语的方法
  • 注意点:

  • 1, type(方法类型)用到时直接去官方文档中有详细的介绍
  • 2, C函数中两个隐式参数的意思 :
    • 1, self:方法调用者
    • _cmd:当前调用方法编号
    • 方法的隐式参数即: 没有暴露出来参数.

总结 : 不懂就去模仿官方文档,里面很详细

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,670评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,928评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,926评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,238评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,112评论 4 356
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,138评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,545评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,232评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,496评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,596评论 2 310
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,369评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,226评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,600评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,906评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,185评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,516评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,721评论 2 335

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,073评论 25 707
  • 转至元数据结尾创建: 董潇伟,最新修改于: 十二月 23, 2016 转至元数据起始第一章:isa和Class一....
    40c0490e5268阅读 1,670评论 0 9
  • 对于从事 iOS 开发人员来说,所有的人都会答出【runtime 是运行时】什么情况下用runtime?大部分人能...
    梦夜繁星阅读 3,693评论 7 64
  • 四天的学习,领略了本真教育的初衷,感受了二七一麾下峡山实验初中与峡山双语小学的办学风采,有收获,更有反思。但是最让...
    知北老师阅读 861评论 7 7
  • 打开一份公文,标题醒目,是“关于进一步做好**微信公众号订阅工作的通知”,这样的文件今年已经不是第一次收到。打开手...
    选择美好阅读 155评论 0 0