極速理解runtime

一枢步、關于runtime簡介

runtime? 顧名思義,就是運行時的意思,是一套底層的 C 語言 API庇谆,其為 iOS 內(nèi)部的核心之一忌锯,我們平時編寫的 OC 代碼幔翰,底層都是基于它來實現(xiàn)的。我們需要了解的是 Objective-C 是一門動態(tài)語言西壮,它會將一些工作放在代碼運行時才處理而并非編譯時遗增。

OC就是運行時機制,也就是在運行時候的一些機制款青,其中最主要的是消息機制做修。

在C語言中,函數(shù)的調(diào)用在編譯的時候會決定調(diào)用哪個函數(shù)抡草。而對于OC的函數(shù)饰及,屬于動態(tài)調(diào)用過程,在編譯的時候并不能決定真正調(diào)用哪個函數(shù)康震,只有在真正運行的時候才會根據(jù)函數(shù)的名稱找到對應的函數(shù)來調(diào)用燎含。

其實事實上在編譯階段,OC可以調(diào)用任何函數(shù)腿短,即使這個函數(shù)并未實現(xiàn)屏箍,只要聲明過就不會報錯

而在c語言中 ,在編譯階段,C語言調(diào)用未實現(xiàn)的函數(shù)就會報錯.

二橘忱、關于runtime作用

由于運行時的應用比較廣泛,我們暫時選擇幾種比較常見的容易理解的來介紹

1.發(fā)送消息

? 方法調(diào)用的本質(zhì)赴魁,就是讓對象發(fā)送消息。使用消息機制前提钝诚,必須導入#import<objc/message.h>

?消息機制原理:對象根據(jù)方法編號SEL去映射表查找對應的方法實現(xiàn)

Student* stu=[[Student alloc]init];

[stu study];

// 本質(zhì):讓對象發(fā)送消息

objc_msgSend(stu, @selector(study));

2.動態(tài)添加方法

如果聲明了某個方法 但是沒有實現(xiàn) ,編譯成功,到那時運行會崩掉

2017-08-30 12:01:00.453 runtimeTest[3228:71218] -[Student study]: unrecognized selector sent to instance 0x60800001ece0

2017-08-30 12:01:00.460 runtimeTest[3228:71218] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[Student study]: unrecognized selector sent to instance 0x60800001ece0'

Student* stu=[[Student alloc]init];

[stu study];

//如果實現(xiàn)了study 打印如下:? 2017-08-30 13:30:01.970 runtimeTest[4004:94732] 正在學習

// 動態(tài)添加方法就不會報錯? 可以通過performSelector調(diào)用颖御,但是會報錯。

[stu performSelector:@selector(study)];

在student.m 中

@implementation Student

//-(void)study

//{

//? ? NSLog(@"正在學習");

//}

//動態(tài)添加

void study(id self ,SEL sel){

//打印出方法名

NSLog(@"%@ %@",self,NSStringFromSelector(sel));

}

// 當一個對象調(diào)用未實現(xiàn)的方法凝颇,會調(diào)用這個方法處理,并且會把對應的方法列表傳過來.

// 剛好可以用來判斷潘拱,未實現(xiàn)的方法是不是我們想要動態(tài)添加的方法

+ (BOOL)resolveInstanceMethod:(SEL)sel

{

if (sel == @selector(study)) {

// 動態(tài)添加eat方法

// 第一個參數(shù):給哪個類添加方法

// 第二個參數(shù):添加方法的方法編號

// 第三個參數(shù):添加方法的函數(shù)實現(xiàn)(函數(shù)地址)

// 第四個參數(shù):函數(shù)的類型,(返回值+參數(shù)類型) v:void @:對象->self :表示SEL->_cmd

class_addMethod(self, @selector(study), study, "v@:");

}

return [super resolveInstanceMethod:sel];

}

@end

再次運行打印結(jié)果如下:

2017-08-30 13:33:38.066 runtimeTest[4093:96918]study

所謂動態(tài)添加就是 + (BOOL)resolveInstanceMethod:(SEL)sel 方法中判斷方法是不是我們需要的,如果是就class_addMethod

3 ?給分類添加屬性

也就是給一個類聲明屬性拧略,其實本質(zhì)就是給這個類添加關聯(lián)

我創(chuàng)建了一個User 類 ,什么都沒添加,并且給創(chuàng)建了一個分類User (Name)

#import "User.h"

@interface User (Name)

@property(nonatomic,strong)NSString* name;

@end

一開始并不實現(xiàn)屬性的方法直接調(diào)用

結(jié)果如下:

2017-08-30 13:45:42.225 runtimeTest[4267:102049] -[User setName:]: unrecognized selector sent to instance 0x608000007f30

2017-08-30 13:45:42.229 runtimeTest[4267:102049] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[User setName:]: unrecognized selector sent to instance 0x608000007f30'

崩潰是在意料之中的

我們再在.m文件做如下處理

#import "User+Name.h"

// 定義關聯(lián)的key

static? char *keyName = "name";

@implementation User (Name)

-(NSString*)name

{

// return objc_getAssociatedObject(<#id object#>, <#const void *key#>)

//第一個參數(shù) 關聯(lián)的object

//第二個參數(shù) 關聯(lián)的key

return objc_getAssociatedObject(self, keyName);

}

-(void)setName:(NSString *)name

{

//objc_setAssociatedObject(<#id object#>, <#const void *key#>, <#id value#>, <#objc_AssociationPolicy policy#>)

// 第一個參數(shù):給哪個對象添加關聯(lián)

// 第二個參數(shù):關聯(lián)的key泽铛,通過這個key獲取

// 第三個參數(shù):關聯(lián)的value

// 第四個參數(shù):關聯(lián)的策略

objc_setAssociatedObject(self, keyName, name, OBJC_ASSOCIATION_RETAIN_NONATOMIC);

}

@end

然后新運行

2017-08-30 13:56:27.299 runtimeTest[4477:107135] ---蚊子---蚊子不吸血

? 4 ? 交換方法

聲明一個分類 NSString+More

#import "NSString+More.h"

#import <objc/runtime.h>

@implementation NSString (More)

//重新添加的一個方法用于交換

+ (void)makestringWithString:(NSString *)string

{

NSLog(@"新方法----%@",string);

NSLog(@"新方法----%@",self);

}

//重寫load方法

+ (void)load

{

//獲取原來containsString的地址

Method containsString=class_getClassMethod(self, @selector(stringWithString:));

//獲取原來addcontainsString的地址

Method addcontainsString=class_getClassMethod(self, @selector(makestringWithString:));

// 交換方法地址,相當于交換實現(xiàn)方式

method_exchangeImplementations(containsString, addcontainsString);

}

@end

調(diào)用方法

NSString* str1=@"23333";

[NSString stringWithString:str1];

結(jié)果如下 ?可以看到執(zhí)行了我們在.m 中實現(xiàn)的方法

2017-08-30 14:23:07.596 runtimeTest[4929:120296] 新方法----23333

2017-08-30 14:23:07.597 runtimeTest[4929:120296] 新方法----NSString

這些基本上足夠淺淺 的入門了,暫時就先介紹到這里 ,蚊子君以后空閑有了新的理解會持續(xù)更新

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末辑鲤,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子杠茬,更是在濱河造成了極大的恐慌月褥,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,194評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件瓢喉,死亡現(xiàn)場離奇詭異宁赤,居然都是意外死亡,警方通過查閱死者的電腦和手機栓票,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評論 2 385
  • 文/潘曉璐 我一進店門决左,熙熙樓的掌柜王于貴愁眉苦臉地迎上來愕够,“玉大人,你說我怎么就攤上這事佛猛』蟀牛” “怎么了?”我有些...
    開封第一講書人閱讀 156,780評論 0 346
  • 文/不壞的土叔 我叫張陵继找,是天一觀的道長遂跟。 經(jīng)常有香客問我,道長婴渡,這世上最難降的妖魔是什么幻锁? 我笑而不...
    開封第一講書人閱讀 56,388評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮边臼,結(jié)果婚禮上哄尔,老公的妹妹穿的比我還像新娘。我一直安慰自己柠并,他們只是感情好岭接,可當我...
    茶點故事閱讀 65,430評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著堂鲤,像睡著了一般亿傅。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上瘟栖,一...
    開封第一講書人閱讀 49,764評論 1 290
  • 那天葵擎,我揣著相機與錄音,去河邊找鬼半哟。 笑死酬滤,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的寓涨。 我是一名探鬼主播盯串,決...
    沈念sama閱讀 38,907評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼戒良!你這毒婦竟也來了体捏?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,679評論 0 266
  • 序言:老撾萬榮一對情侶失蹤糯崎,失蹤者是張志新(化名)和其女友劉穎几缭,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體沃呢,經(jīng)...
    沈念sama閱讀 44,122評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡年栓,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,459評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了薄霜。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片某抓。...
    茶點故事閱讀 38,605評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡纸兔,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出否副,到底是詐尸還是另有隱情汉矿,我是刑警寧澤,帶...
    沈念sama閱讀 34,270評論 4 329
  • 正文 年R本政府宣布副编,位于F島的核電站负甸,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏痹届。R本人自食惡果不足惜呻待,卻給世界環(huán)境...
    茶點故事閱讀 39,867評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望队腐。 院中可真熱鬧蚕捉,春花似錦、人聲如沸柴淘。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,734評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽为严。三九已至敛熬,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間第股,已是汗流浹背应民。 一陣腳步聲響...
    開封第一講書人閱讀 31,961評論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留夕吻,地道東北人诲锹。 一個月前我還...
    沈念sama閱讀 46,297評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像涉馅,于是被迫代替她去往敵國和親归园。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,472評論 2 348

推薦閱讀更多精彩內(nèi)容

  • 轉(zhuǎn)至元數(shù)據(jù)結(jié)尾創(chuàng)建: 董瀟偉稚矿,最新修改于: 十二月 23, 2016 轉(zhuǎn)至元數(shù)據(jù)起始第一章:isa和Class一....
    40c0490e5268閱讀 1,686評論 0 9
  • ping怎么這么高庸诱? 什么是Runtime? 這還要說晤揣?run( 運行)桥爽、time(時),runtime(運行時)...
    大大盆子閱讀 646評論 1 1
  • 轉(zhuǎn)載:http://yulingtianxia.com/blog/2014/11/05/objective-c-r...
    F麥子閱讀 729評論 0 2
  • 本文詳細整理了 Cocoa 的 Runtime 系統(tǒng)的知識碉渡,它使得 Objective-C 如虎添翼,具備了靈活的...
    lylaut閱讀 795評論 0 4
  • 本文轉(zhuǎn)載自:http://yulingtianxia.com/blog/2014/11/05/objective-...
    ant_flex閱讀 749評論 0 1