
duwenquan-方形LOGO.png
引述
在iOS開發(fā)中,在項目中經(jīng)常會發(fā)現(xiàn)一些奇怪的功能。不太能找的到代碼的出處,但卻實現(xiàn)了功能,很可能這是實用了黑魔法Runtime?!尽兑徊讲酱罱词雇ㄓ嵖蚣堋吩赗untime系列博文之后推出】,謝謝您的支持。
Runtime簡介
- Runtime簡稱運行時。OC就是運行時機制,也就是在運行時候的一些機制,其中最主要的是消息機制。
- 對于C語言,函數(shù)的調(diào)用在編譯的時候會決定調(diào)用哪個函數(shù)。
- 對于OC的函數(shù),屬于動態(tài)調(diào)用過程,在編譯的時候并不能決定真正調(diào)用哪個函數(shù),只有在真正運行的時候才會根據(jù)函數(shù)的名稱找到對應(yīng)的函數(shù)來調(diào)用。
- 事實證明:
在編譯階段,OC可以調(diào)用任何函數(shù),即使這個函數(shù)并未實現(xiàn),只要聲明過就不會報錯。
在編譯階段,C語言調(diào)用未實現(xiàn)的函數(shù)就會報錯。
Runtime運用-消息機制
我們在開發(fā)中,運用最多的就是方法的調(diào)用,其實方法調(diào)用的本質(zhì)就是發(fā)送消息。假設(shè)我們定義一個Cat類,它有兩個方法,一個對象方法eat;一個類方法eat;示例如下:
#import "Cat.h"
@implementation Cat
-(void)eat{
NSLog(@"對象方法---我要吃魚了");
}
+(void)eat{
NSLog(@"類方法---我要吃魚了");
}
@end
如果我們想在一個控制器中使用這個方法,通常我們的做法是,先引入頭文件"Cat.h",如果是調(diào)用對象方法,那就用alloc先創(chuàng)建一個對象,再調(diào)用對象方法,如果是調(diào)用類方法,直接通過類名就可以調(diào)用。示例如下:
/*調(diào)用對象方法通常做法1*/
// Cat *cat1=[[Cat alloc]init];
//
// [cat1 eat];
/*調(diào)用對象方法通常做法2*/
Cat *cat2=[[Cat alloc]init];
[cat2 performSelector:@selector(eat)];
// SEL:方法編號,根據(jù)方法編號就可以找到對應(yīng)方法實現(xiàn),此方法其實就是運用了運行時。
/*運行時方法*/
/*調(diào)用類方法通常做法1*/
[Cat eat];//通過類名調(diào)用
/*調(diào)用類方法通常做法2*/
[[Cat class]eat];//通過類對象調(diào)用
其實上述方法的本質(zhì)都是消息發(fā)送,那么接下來我們看用Runtime如何實現(xiàn)調(diào)用eat方法
- 1.第一步:引入Runtime框架import <objc/message.h>,注意,使用message,不使用<objc/runtime.h>的原因是message.h涵蓋runtime,方法更全。
- 2.第二步:Build Setting -> 搜索msg -> 設(shè)置屬性為No
- 3.使用objc_msgSend,方法;注意:只有對象才能發(fā)送消息,因此以objc開頭.
//運行時方法
// 運行時,發(fā)送消息,誰做事情就拿誰
// xcode5之后,蘋果不建議使用底層方法
// xcode5之后,使用運行時.
// 讓cat發(fā)送消息-對象
Cat *cat3=[[Cat alloc]init];
objc_msgSend(cat3, @selector(eat));
//類方法使用runtime
// 獲取類對象
Class catClass = [Cat class];
// 運行時
objc_msgSend(catClass, @selector(eat));
Runtime原理導(dǎo)圖及其使用效果展示

消息機制原理.png

Runtime消息機制.png
Runtime消息機制使用Demo下載地址
Runtime消息機制Demo
廣大書友在學(xué)習(xí)的同時請給個點贊,在GitHub上給個Star噢~~~~~~!