35.runtime(消息机制)

一.runtime简介

  • Runtime简称运行时,OC就是运行时机制,也就是在运行的时候的一些机制,其中最主要的是消息机制.

  • 对于C语言,函数的调用在编译的时候会决定调用哪个函数.

  • 对于oc的函数,属于动态调用过程,在编译的时候并不能真正调用哪个函数,只有在真正运行的时候才会根据函数的名称找到对应的函数来调用.

  • 事实证明:

  • (1).在编译阶段,oc可以调用任何函数,即使这个函数并未实现,只要声明过就不会报错.

  • (2).在编译阶段,c语言调用未实现的函数就会报错

OC:运行时机制,消息机制是运行时机制最重要的机制
消息机制:任何方法调用,本质都是发送消息

二.runtime的使用

运行时,发送消息,谁做事请就拿谁
xcode5 之后,苹果不建议使用底层的方法
** xcode5之后,使用运行时**(使用运行时的原因)

(1).方法调用的本质,就是让对象发送消息.objc_msgSend只有对象才能发消息,因此以objc开头,使用消息机制前提,必须导入#import <objc/message.h>

(2).Build Setting -> 搜索msg -> 设置属性为NO

运行时

(3).真正的使用

在外面我定义了一个Person的类,方法都进行了实现

Person

消息机制调用对象方法:(调用的是多个参数的)

 objc_msgSend(person, @selector(run:sdd:),25,@"名字");

额外提一句:类方法的调用:本质是把类名转化为类对象

//类方法的调用:本质是把类名转化为类对象
1.[Person eat];
2.[[Person class]performSelector:@selector(eat)];
3.
id personClass = [Person class];
[personClass performSelector:@selector(eat)];

类方法运行机制的调用:

objc_msgSend([Person class], @selector(eat));

如果用一张图来表示的话就是下面的:

**运行时调用机制**

1.先用对象 -> 2.performSelector -> 3.@selector(方法:类似键)+有参数就添加 ->
4.这个对象的方法库里面寻找方法 -> 5.找到这个方法来调用

三.runtime交换方法

UIImage+Image.h
#import <UIKit/UIKit.h>
@interface UIImage (Image)

+(__kindof UIImage *) jk_imageNamed:(NSString *)imageName;

@end

UIImage+Image.m
#import "UIImage+Image.h"
#import <objc/message.h>
@implementation UIImage (Image)
//交换的方法实现,方法都定义在类里面

/**
 *  Class : 获取哪个类方法
 *  SEL : 获取方法编号,根据SEL就能去对应的类找方法
 */

//获取类方法
//class_getClassMethod(<#__unsafe_unretained Class cls#>, <#SEL name#>)

//获取对象方法
//class_getInstanceMethod(<#__unsafe_unretained Class cls#>, <#SEL name#>)

+(void)load
{
//交换方法实现

//获取类方法
Method imageMethod = class_getClassMethod([UIImage class], @selector(imageNamed:));

Method jk_imageMethod = class_getClassMethod([UIImage class], @selector(jk_imageNamed:));

method_exchangeImplementations(imageMethod, jk_imageMethod);

}

+(UIImage *)jk_imageNamed:(NSString *)imageName
{
   UIImage *image = [UIImage jk_imageNamed:imageName];

   if (image == nil) {
    
      NSLog(@"图片为空");
    }else
    {

       NSLog(@"图片不为空");
    }
  return image;
}

四.runtime动态添加方法(这里添加的是带参数的方法)

在此定义的是一个Son方法

//
//  Son.m
//  OC的runtime

#import "Son.h"
#import <objc/message.h>
@implementation Son

//定义函数
void eat(id self,SEL _cmd,id patam1)
{
/**
 *  系统默认会传方法
 *
 */
NSLog(@"调用eat %@ %@ %@",self,NSStringFromSelector(_cmd),patam1);

}

//默认一个方法有两个参数,self,_cmd
//self:方法的调用者
//_cmd:调用方法的编号

//动态添加方法,首先实现这个(没有实现的方法会走这里)
+(BOOL) resolveInstanceMethod:(SEL)sel
{

//动态添加eat方法

/**
 *  对象方法的方法添加解释
 *
 *  @param cls#>    给那个类添加方法
 *  @param SEL#>    添加方法的方法编号
 *  @param imp#>    方法实现,函数入口,函数名
 *  @param types#>  方法类型
 *
 */
// class_addMethod(<#__unsafe_unretained Class cls#>, <#SEL name#>, <#IMP imp#>, <#const char *types#>)

    if ([NSStringFromSelector(sel) isEqualToString:@"eat:"])
    {
    
       // @:对象 : SEL
       class_addMethod(self, sel, (IMP)eat, "v@:@");
    
        return YES;
     }

     return [super resolveInstanceMethod:sel];
}
@end

五.runtime动态添加属性

给一个类动态的添加属性

我写了一个NSObject+shuxing.h类

NSObject+shuxing.h
生命一个属性

 @property(nonatomic,strong) NSString *name;

NSObject+shuxing.m

#import "NSObject+shuxing.h"
#import <objc/message.h>

@implementation NSObject (shuxing)

-(void)setName:(NSString *)name
{
//添加属性与对象有关
//给某个对象产生关联
/**
 *  id object  给哪个对象添加属性
 *  const void *key 属性名,根据key去获取关联的对象  void * == id
 *  id value  关联的值
 *  objc_AssociationPolicy policy  策略,用什么策略去保存
 */
 objc_setAssociatedObject(self, @"name", name, OBJC_ASSOCIATION_RETAIN_NONATOMIC);

}
-(NSString *)name
{
   return objc_getAssociatedObject(self, @"name");
}
@end

runtime部分代码 密码: kd5y

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

推荐阅读更多精彩内容

  • 转至元数据结尾创建: 董潇伟,最新修改于: 十二月 23, 2016 转至元数据起始第一章:isa和Class一....
    40c0490e5268阅读 1,670评论 0 9
  • 这篇文章完全是基于南峰子老师博客的转载 这篇文章完全是基于南峰子老师博客的转载 这篇文章完全是基于南峰子老师博客的...
    西木阅读 30,521评论 33 466
  • 对于从事 iOS 开发人员来说,所有的人都会答出【runtime 是运行时】什么情况下用runtime?大部分人能...
    梦夜繁星阅读 3,693评论 7 64
  • Runtime是什么 Runtime 又叫运行时,是一套底层的 C 语言 API,其为 iOS 内部的核心之一,我...
    SuAdrenine阅读 863评论 0 3
  • 参考链接: http://www.cnblogs.com/ioshe/p/5489086.html 简介 Runt...
    乐乐的简书阅读 2,125评论 0 9