借閱:貓貓學(xué)iOS之RunTime理解運(yùn)用
一:RunTime簡(jiǎn)介
Objective-C是一門動(dòng)態(tài)語言,他將一些工作從編譯階段推遲到了運(yùn)行階段,比如調(diào)用方法:
在C語音當(dāng)中,調(diào)用方法在編譯的時(shí)候就知道具體調(diào)用哪個(gè)方法;(C語言調(diào)用 未實(shí)現(xiàn)的方法 就會(huì)報(bào)錯(cuò))
1.1 如圖1.1 在掉用只聲明而沒有實(shí)現(xiàn)的方法,在編譯的時(shí)候就直接報(bào)錯(cuò)了。
圖1.2
1.2 正確的應(yīng)該是圖1.2
在Objective-C語音當(dāng)中,調(diào)用方法是動(dòng)態(tài)的,在編譯的時(shí)候并不能真正決定調(diào)用哪個(gè)方法(只要有聲明,既是沒有實(shí)現(xiàn)就不會(huì)報(bào)錯(cuò)),只有在真正運(yùn)行的時(shí)候才會(huì)根據(jù)方法的編號(hào)(名稱)找到對(duì)應(yīng)的方法來調(diào)用。
2.1
2.1 圖2.1中定義了Cat類,然后聲明了吃食物的方法,沒有實(shí)現(xiàn)方法的情況下只是報(bào)了警告,但是在運(yùn)行的時(shí)候就會(huì)報(bào)錯(cuò):Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[Cat eatWithFood:]: unrecognized selector sent to instance 0x7f9b1b4da8e0'
//定義類@interface Cat : NSObject- (void)eatWithFood:(NSString *)food;+ (void)eatWithFood:(NSString *)food;@end@implementation Cat@end//調(diào)用Cat *cat = [[Cat alloc]init];[cat eatWithFood:@"魚"];
RunTime翻譯過來就是運(yùn)行時(shí),其實(shí)就是OC的運(yùn)行時(shí)機(jī)制,搜索runtime會(huì)發(fā)現(xiàn)很多都有運(yùn)行時(shí)機(jī)制,簡(jiǎn)單說就是運(yùn)行的時(shí)候的一些機(jī)制,在OC中最主要的就是消息機(jī)制
二:RunTime的準(zhǔn)備
xcode5之后,蘋果不建議使用底層的方法,xcode5之后,使用運(yùn)行時(shí)要做一些編譯的設(shè)置,我們可以修改下,解決如下圖:Build Settings -> 搜索msg 講對(duì)應(yīng)yes改為no(嚴(yán)肅的檢查oc的消息機(jī)制)
三:RunTime的運(yùn)用
定義貓類并且實(shí)現(xiàn)方法,后面都是根據(jù)這個(gè)類玩的。
@interface Cat : NSObject- (void)eatWithFood:(NSString *)food;+ (void)eatWithFood:(NSString *)food;@end@implementation Cat-(void)eatWithFood:(NSString *)food{ NSLog(@"對(duì)象方法———— 對(duì)象貓?jiān)诔?@",food);}+(void)eatWithFood:(NSString *)food{ NSLog(@"類方法———— 貓類在吃%@",food);}@end
1、RunTime調(diào)用對(duì)象方法
//初始化對(duì)象 Cat *cat = [[Cat alloc]init]; //最常用的方法調(diào)用 [cat eatWithFood:@"魚"]; //perfor方法調(diào)用 [cat performSelector:@selector(eatWithFood:) withObject:@"肉"]; //runtime調(diào)用 objc_msgSend(cat, @selector(eatWithFood:),@"老鼠");
其實(shí)這三種方式最終都會(huì)用runtime來執(zhí)行。
2、RunTime調(diào)用類方法
//最常用的方法調(diào)用 [Cat eatWithFood:@"魚"]; //類對(duì)象 Class catClass = [Cat class]; //perfor方法調(diào)用 [catClass performSelector:@selector(eatWithFood:) withObject:@"肉"]; //runtime調(diào)用 objc_msgSend(catClass, @selector(eatWithFood:),@"老鼠");
對(duì)于類方法來說,其實(shí)其本質(zhì)還是說用對(duì)象調(diào)用方法,已知,對(duì)象調(diào)用方法的本質(zhì)是讓對(duì)象發(fā)送消息,我們可以看出,類方法的調(diào)用其實(shí)就是底層讓類對(duì)象發(fā)送消息,從而實(shí)習(xí)類方法的調(diào)用。
這里其實(shí)很繞,學(xué)過java的都應(yīng)該理解過一個(gè)概念,指向類的類,學(xué)過C的都知道另一個(gè)更牛逼的概念,指向指針的指針。。。總之,當(dāng)年理解這些的時(shí)候貓就一個(gè)感覺:『這他喵的都是些什么鬼』
其實(shí)這個(gè)也不是很難理解,類是什么?就是一類事物嘛,比如貓類是一個(gè)類,我家的貓是一個(gè)貓對(duì)象,那么同理,對(duì)于抽象『類』這一類事物的總稱,我們可以稱之為類類,(這東西用中文更繞)就是我們?cè)诖a中看到的 Class ,而上述代碼中的catClass 就是Class 的一個(gè)對(duì)象,我們可以用catClass來代表 Cat這個(gè)類,這也就是說 catClass 是表示Cat類的類。** 好吧,在說下我的理解吧,我們平時(shí)定義類的時(shí)候,一般都有方法和屬性(其他的isa都不考慮), 貓有一些屬性,還有方法,我們可以將之抽象成代碼 Cat類,狗也有屬性和方法,人也有。。。萬物都有,于是我們可以將這些都有屬性和方法的東東抽象成一個(gè)類,稱之為類類(Class)而像貓類,狗類,人類等等都是這個(gè)類的一個(gè)對(duì)象。
消息機(jī)制原理:對(duì)象根據(jù)方法編號(hào)SEL去映射表查找對(duì)應(yīng)的方法實(shí)現(xiàn)
圖來源于網(wǎng)絡(luò)
文/翟乃玉(簡(jiǎn)書作者)原文鏈接:http://www.lxweimin.com/p/e1c04d6de1d3著作權(quán)歸作者所有,轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán),并標(biāo)注“簡(jiǎn)書作者”。