OC_Runtime小筆記

最近開(kāi)始在上海實(shí)習(xí),在公司負(fù)責(zé)研究JSPatch熱修復(fù)的相關(guān)事務(wù),其中需要好好學(xué)習(xí)一下Runtime宿百,這一塊是OC里面比較晦澀的東西轮纫,現(xiàn)將學(xué)習(xí)心得記錄下來(lái)腔寡。

邊寫(xiě)邊學(xué)

有兩個(gè)類(lèi):ViewControllerNewViewController,分別有一個(gè)打印方法:testnewTest掌唾。

- (void)test
{
    NSString *cls = NSStringFromClass([self class]);
    NSString *sle = NSStringFromSelector(_cmd);
    NSLog(@"origin methods: <%@> [%@]", cls, sle);
}
- (void)newTest
{
    NSString *cls = NSStringFromClass([self class]);
    NSString *sle = NSStringFromSelector(_cmd);
    NSLog(@"now replaced method: <%@> [%@]", cls, sle);
}

下面可以在AppDelegate中的application:didFinishLaunchingWithOptions:執(zhí)行以下代碼放前,查看輸出結(jié)果,理解Runtime中動(dòng)態(tài)消息轉(zhuǎn)發(fā)的細(xì)節(jié)糯彬。
代碼各部分的執(zhí)行說(shuō)明可以見(jiàn)注釋凭语。

    // 原本要執(zhí)行的實(shí)例中的方法
    Class oriCls = NSClassFromString(@"ViewController");
    id viewController = [[oriCls alloc] init];
    SEL oriSel = NSSelectorFromString(@"test");
    [viewController performSelector:oriSel];
    
    Method oriMethod = class_getInstanceMethod(oriCls, oriSel);
    IMP originIMP = method_getImplementation(oriMethod);
    const char *oriTypes = method_getTypeEncoding(oriMethod);
    /*
    1、performSelector是運(yùn)行時(shí)系統(tǒng)負(fù)責(zé)去找方法的撩扒,在編譯時(shí)候不做任何校驗(yàn)似扔;如果直接調(diào)用編譯是會(huì)自動(dòng)校驗(yàn)。如果imageDownloader:didFinishWithImage:image:不存在搓谆,那么直接調(diào)用 在編譯時(shí)候就能夠發(fā)現(xiàn)(借助Xcode可以寫(xiě)完就發(fā)現(xiàn))炒辉,但是使用performSelector的話一定是在運(yùn)行時(shí)候才能發(fā)現(xiàn)(此時(shí)程序崩潰);Cocoa支持在運(yùn)行時(shí)向某個(gè)類(lèi)添加方法泉手,即方法編譯時(shí)不存在黔寇,但是運(yùn)行時(shí)候存在,這時(shí)候必然需要使用performSelector去調(diào)用斩萌。所以有時(shí)候如果使用了performSelector缝裤,為了程序的健壯性,會(huì)使用檢查方法
    - (BOOL)respondsToSelector:(SEL)aSelector;
    2颊郎、直接調(diào)用方法時(shí)候憋飞,一定要在頭文件中聲明該方法的使用,也要將頭文件import進(jìn)來(lái)姆吭。而使用performSelector時(shí)候榛做, 可以不用import頭文件包含方法的對(duì)象,直接用performSelector調(diào)用即可猾编。
     */
    
    
    
    // 現(xiàn)在替換IMP指針到NewViewController中的newTest中
    Class newCls = NSClassFromString(@"NewViewController");
    SEL newSle = NSSelectorFromString(@"newTest");
    Method newMethod = class_getInstanceMethod(newCls, newSle);
    
    //IMP replaceIMP = class_getMethodImplementation(newCls, newSle);
    IMP replaceIMP = method_getImplementation(newMethod);
    const char *newTypes = method_getTypeEncoding(newMethod);
    
    // 然后繼續(xù)執(zhí)行原方法瘤睹,原方法的Class和SEL仍舊是ViewController和test,但是動(dòng)態(tài)執(zhí)行時(shí)被替換成了NewViewController和newTest
    class_replaceMethod(oriCls, oriSel, replaceIMP, newTypes);
    // 新增一個(gè)oriTest方法答倡,指向原來(lái)的test實(shí)現(xiàn)
    class_addMethod(oriCls,@selector(oriTest), originIMP, oriTypes);
    
    
    [viewController performSelector:oriSel];
    [viewController performSelector:@selector(oriTest)];

執(zhí)行結(jié)果如下圖:

執(zhí)行結(jié)果

從結(jié)果中可以清楚地看到方法的替換和保存轰传。

完善內(nèi)容,待更~

如果這篇文章對(duì)您有幫助瘪撇,歡迎點(diǎn)贊和轉(zhuǎn)發(fā)获茬。有任何問(wèn)題或者建議港庄,也歡迎留言!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末恕曲,一起剝皮案震驚了整個(gè)濱河市鹏氧,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌佩谣,老刑警劉巖把还,帶你破解...
    沈念sama閱讀 218,451評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異茸俭,居然都是意外死亡吊履,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,172評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門(mén)调鬓,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)艇炎,“玉大人,你說(shuō)我怎么就攤上這事腾窝∽鹤伲” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,782評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵虹脯,是天一觀的道長(zhǎng)驴娃。 經(jīng)常有香客問(wèn)我,道長(zhǎng)循集,這世上最難降的妖魔是什么托慨? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,709評(píng)論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮暇榴,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘蕉世。我一直安慰自己蔼紧,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,733評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布狠轻。 她就那樣靜靜地躺著奸例,像睡著了一般。 火紅的嫁衣襯著肌膚如雪向楼。 梳的紋絲不亂的頭發(fā)上查吊,一...
    開(kāi)封第一講書(shū)人閱讀 51,578評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音湖蜕,去河邊找鬼逻卖。 笑死,一個(gè)胖子當(dāng)著我的面吹牛昭抒,可吹牛的內(nèi)容都是我干的评也。 我是一名探鬼主播炼杖,決...
    沈念sama閱讀 40,320評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼盗迟!你這毒婦竟也來(lái)了坤邪?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,241評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤罚缕,失蹤者是張志新(化名)和其女友劉穎艇纺,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體邮弹,經(jīng)...
    沈念sama閱讀 45,686評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡黔衡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,878評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了肠鲫。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片员帮。...
    茶點(diǎn)故事閱讀 39,992評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖导饲,靈堂內(nèi)的尸體忽然破棺而出捞高,到底是詐尸還是另有隱情,我是刑警寧澤渣锦,帶...
    沈念sama閱讀 35,715評(píng)論 5 346
  • 正文 年R本政府宣布硝岗,位于F島的核電站,受9級(jí)特大地震影響袋毙,放射性物質(zhì)發(fā)生泄漏型檀。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,336評(píng)論 3 330
  • 文/蒙蒙 一听盖、第九天 我趴在偏房一處隱蔽的房頂上張望胀溺。 院中可真熱鬧,春花似錦皆看、人聲如沸仓坞。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,912評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)无埃。三九已至,卻和暖如春毛雇,著一層夾襖步出監(jiān)牢的瞬間嫉称,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,040評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工灵疮, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留织阅,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,173評(píng)論 3 370
  • 正文 我出身青樓震捣,卻偏偏與公主長(zhǎng)得像蒲稳,于是被迫代替她去往敵國(guó)和親氮趋。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,947評(píng)論 2 355

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

  • 背景 在我們實(shí)際開(kāi)發(fā)的ios項(xiàng)目中,使用了Jspatch和Aspect兩個(gè)第三方庫(kù) 先說(shuō)下這兩個(gè)是什么東東祥国,能用來(lái)...
    咖啡兌水閱讀 1,630評(píng)論 1 14
  • 轉(zhuǎn)載:http://yulingtianxia.com/blog/2014/11/05/objective-c-r...
    F麥子閱讀 734評(píng)論 0 2
  • 文中的實(shí)驗(yàn)代碼我放在了這個(gè)項(xiàng)目中昵观。 以下內(nèi)容是我通過(guò)整理[這篇博客] (http://yulingtianxia....
    茗涙閱讀 923評(píng)論 0 6
  • 本文詳細(xì)整理了 Cocoa 的 Runtime 系統(tǒng)的知識(shí),它使得 Objective-C 如虎添翼舌稀,具備了靈活的...
    lylaut閱讀 800評(píng)論 0 4
  • 江湖夜雨啊犬,十年燈,一劍輕似飛花壁查,更勝夢(mèng)觉至。憶當(dāng)年,樓空人不去睡腿,鴻雁幾度歸语御? 嘆人生,影下花落席怪,步無(wú)塵应闯,殘?jiān)卤M傷。半點(diǎn)...
    竹鴻初閱讀 584評(píng)論 0 1