RunTime運行時(三)

轉自原文地址:http://blog.csdn.net/wzzvictory/article/details/8629036

學了那么久的Objective-C,給我的感覺就是它什么都是動態(tài)的撵割,你將會聽到一個新的名詞:

一、動態(tài)方法解析

  • 1包颁、+(BOOL) resolveInstanceMethod:(SEL) sel

這是NSObject根類提供的類方法瞻想,調用時機為當被調用的方法實現部分沒有找到,而消息轉發(fā)機制啟動之前的這個中間時刻娩嚼。

  • 2蘑险、@dynamic關鍵字

Objective-C2.0 提供了@dynamic關鍵字。這個關鍵字有兩個作用:

①告訴編譯器不要創(chuàng)建實現屬性所用的實例變量岳悟;

②告訴編譯器不要創(chuàng)建該屬性的get和setter方法佃迄。

如果我們在@interface接口文件中聲明了一個屬性,如下所示:

@property(nonatomic,retain) NSString    *name; 

默認情況下贵少,編譯器會為當前類自動生成一個NSString *_name的實例變量(如果想改變實例變量的名稱可以用@synthesize關鍵字)呵俏,同時會生成兩個名為- (NSString *)name和- (void)setName:(NSString *)aName的存取方法。

而@dynamic關鍵字就是告訴編譯器不要做這些事滔灶,同時在使用了存取方法時也不要報錯普碎,即讓編譯器相信存取方法會在運行時找到。

比如在@implementation文件中做了如下聲明:

@dynamic name;  

如果使用了name屬性的setter方法录平,又不想在運行時崩潰麻车,就可以在運行時做點動作:

void dynamicMethodIMP(id self, SEL _cmd)  
{  
    // implementation ....  
}  
  
+ (BOOL)resolveInstanceMethod:(SEL)sel  
{  
    NSLog(@"sel is %@", NSStringFromSelector(sel));  
    if(sel == @selector(setName:)){  
        class_addMethod([self class],sel,(IMP)dynamicMethodIMP,"v@:");  
        return YES;  
    }  
    return [super resolveInstanceMethod:sel];  
}  

在resolveInstanceMethod的實現中,我們通過class_addMethod方法動態(tài)的向當前對象增加了dynamicMethodIMP函數斗这,來代替-(void)setName:(NSString *)name的實現部分动猬,從而達到了動態(tài)生成name屬性方法的目的。

值得說明的是:

①在上個例子中涝影,我們自己實現了-(void)setName:(NSString *)name方法枣察,則在運行的時候争占,調用完我們實現的-(void)setName:(NSString *)name方法后燃逻,運行時系統仍然會調+(BOOL) resolveInstanceMethod:(SEL) sel方法,只不過這里的sel會變成_doZombieMe臂痕,從而我們實現重定向的if分支就進不去了伯襟,即我們實現的方法不會被覆蓋。

②"v@:"屬于Objective-C類型編碼的內容握童,感興趣的同學可以自己google一下姆怪。

二、runtime system消息轉發(fā)機制

對象是謙恭的澡绩,它會接收所有發(fā)送過來的消息稽揭,哪怕這些消息自己無法響應。問題來了:當對象無法響應這些消息時怎么辦肥卡?runtime提供了消息轉發(fā)機制來處理該問題溪掀。

當外部調用的某個方法對象沒有實現,而且resolveInstanceMethod方法中也沒有做重定向處理時步鉴,就會觸發(fā)- (void)forwardInvocation:(NSInvocation *)anInvocation方法揪胃。在該方法中璃哟,可以實現對不能處理的消息做的一些默認處理,也可以以其它的某種方式來避免錯誤被拋出。像forwardInvocation:的名字一樣,這個方法通常用來將不能處理的消息轉發(fā)給其它的對象喊递。通常我們重寫該方法的方式如下所示:

-(void)forwardInvocation:(NSInvocation *)invocation  
{  
    SEL invSEL = invocation.selector;  
    if ([someOtherObject respondsToSelector:invSEL])  
        [anInvocation invokeWithTarget:someOtherObject];  
    } else {  
        [self doesNotRecognizeSelector:invSEL];   
    }                                          
}  

怎么看著有點像多繼承呀随闪??骚勘?你說對了铐伴,消息轉發(fā)提供了多重繼承的很多特性。然而,兩者有很大的不同:多重繼承是將不同的行為封裝到單個的對象中,有可能導致龐大的,復雜的對象俏讹。而消息轉發(fā)是將問題分解到更小的對象中,但是又以一種對消息發(fā)送對象來說完全透明的方式將這些對象聯系起來盛杰。總之藐石,Objective-C通過這種方式即供,一定程度上減小了自己不支持多繼承的劣勢。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末于微,一起剝皮案震驚了整個濱河市逗嫡,隨后出現的幾起案子,更是在濱河造成了極大的恐慌株依,老刑警劉巖驱证,帶你破解...
    沈念sama閱讀 223,002評論 6 519
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現場離奇詭異恋腕,居然都是意外死亡抹锄,警方通過查閱死者的電腦和手機,發(fā)現死者居然都...
    沈念sama閱讀 95,357評論 3 400
  • 文/潘曉璐 我一進店門荠藤,熙熙樓的掌柜王于貴愁眉苦臉地迎上來伙单,“玉大人,你說我怎么就攤上這事哈肖∥怯” “怎么了?”我有些...
    開封第一講書人閱讀 169,787評論 0 365
  • 文/不壞的土叔 我叫張陵淤井,是天一觀的道長布疼。 經常有香客問我,道長币狠,這世上最難降的妖魔是什么游两? 我笑而不...
    開封第一講書人閱讀 60,237評論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮漩绵,結果婚禮上贱案,老公的妹妹穿的比我還像新娘。我一直安慰自己渐行,他們只是感情好轰坊,可當我...
    茶點故事閱讀 69,237評論 6 398
  • 文/花漫 我一把揭開白布铸董。 她就那樣靜靜地躺著,像睡著了一般肴沫。 火紅的嫁衣襯著肌膚如雪粟害。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,821評論 1 314
  • 那天颤芬,我揣著相機與錄音悲幅,去河邊找鬼。 笑死站蝠,一個胖子當著我的面吹牛汰具,可吹牛的內容都是我干的。 我是一名探鬼主播菱魔,決...
    沈念sama閱讀 41,236評論 3 424
  • 文/蒼蘭香墨 我猛地睜開眼留荔,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了澜倦?” 一聲冷哼從身側響起聚蝶,我...
    開封第一講書人閱讀 40,196評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎藻治,沒想到半個月后碘勉,有當地人在樹林里發(fā)現了一具尸體,經...
    沈念sama閱讀 46,716評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡桩卵,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,794評論 3 343
  • 正文 我和宋清朗相戀三年验靡,在試婚紗的時候發(fā)現自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片雏节。...
    茶點故事閱讀 40,928評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡胜嗓,死狀恐怖,靈堂內的尸體忽然破棺而出矾屯,到底是詐尸還是另有隱情兼蕊,我是刑警寧澤,帶...
    沈念sama閱讀 36,583評論 5 351
  • 正文 年R本政府宣布件蚕,位于F島的核電站,受9級特大地震影響产禾,放射性物質發(fā)生泄漏排作。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,264評論 3 336
  • 文/蒙蒙 一亚情、第九天 我趴在偏房一處隱蔽的房頂上張望妄痪。 院中可真熱鬧,春花似錦楞件、人聲如沸衫生。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,755評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽罪针。三九已至彭羹,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間泪酱,已是汗流浹背派殷。 一陣腳步聲響...
    開封第一講書人閱讀 33,869評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留墓阀,地道東北人毡惜。 一個月前我還...
    沈念sama閱讀 49,378評論 3 379
  • 正文 我出身青樓,卻偏偏與公主長得像斯撮,于是被迫代替她去往敵國和親经伙。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,937評論 2 361

推薦閱讀更多精彩內容

  • 轉至元數據結尾創(chuàng)建: 董瀟偉勿锅,最新修改于: 十二月 23, 2016 轉至元數據起始第一章:isa和Class一....
    40c0490e5268閱讀 1,735評論 0 9
  • 我們常常會聽說 Objective-C 是一門動態(tài)語言橱乱,那么這個「動態(tài)」表現在哪呢?我想最主要的表現就是 Obje...
    Ethan_Struggle閱讀 2,199評論 0 7
  • 本文轉載自:http://southpeak.github.io/2014/11/03/objective-c-r...
    idiot_lin閱讀 382評論 0 0
  • 我被打了,莫名其妙的被打了茶宵。 肇事者顯然早有預謀危纫,蒙住我的頭一頓拳打腳踢,一邊打還一邊說王大柱,叫你勾引人家老婆乌庶。...
    過世界邊閱讀 709評論 16 16
  • 姓名:張亞妮 公司:慈星股份 【知~學習】 《六項精進》大綱背誦0遍 共30遍 《六項精進》通篇誦讀0遍 共...
    宇嘟嘟閱讀 99評論 0 0