iOS Runtime 小試(1)

runtime在平時簡單的開發中很少用到,但這個涉及到底層,做iOS的不懂runtime就等于功夫只學了招式沒有修煉內功,最多只能是個高手,懂的api多點,但運行機制不通。api學不完,但底層運行機制是不變的。所有今天主要學習了下runtime。自己寫的代碼
我先看了一個視頻 iOS runtime 分享 總結下里面講了兩個知識點。
1 交換方法實現

+ (void)load{
    
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        Class cls = [UILabel class];
        SEL original = @selector(willMoveToSuperview:);
        SEL swizzled = @selector(myWillMoveToSuperview:);
        
        Method originalMethod   = class_getInstanceMethod(cls, original);
        Method swizzledMethod   = class_getInstanceMethod(cls, swizzled);
        
        //添加自定義的方法到類里面
        BOOL didAddMethod = class_addMethod(cls, original, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod));
/**
         swizzled 是存在于 UILabel 的方法列表中
         original 是存在于 UILabel 的父類方法列表中,不存在在UILabel中。 
         所以class_addMethod 是給UILabel添加一個選擇器,相當于重寫了父類的方法。
         重寫的方法名,追加另外一個函數的實現。
         */
        if (didAddMethod) {
            //方法已經添加成功  替換掉原來的方法實現
            class_replaceMethod(cls, swizzled, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod));
        }else{
            //沒有添加成功    改變兩個函數的實現
            method_exchangeImplementations(originalMethod, swizzledMethod);
        }
    });
}

- (void)myWillMoveToSuperview:(nullable UIView *)newSuperview{
    
    [self myWillMoveToSuperview:newSuperview];
    if (newSuperview) {
        self.backgroundColor = [UIColor yellowColor];
        [self setFont:[UIFont systemFontOfSize:13]];
    }
}

method_exchangeImplementations 改變兩個方法的實現
很多人可能會認為上面的myWillMoveToSuperview:會循環執行,其實不會的。我來捋一捋。交換地址后 系統會調用willMoveToSuperview,可這時候willMoveToSuperview 指向了 myWillMoveToSuperview,于是就執行

 {
 [self myWillMoveToSuperview:newSuperview];
    if (newSuperview) {
        self.backgroundColor = [UIColor yellowColor];
        [self setFont:[UIFont systemFontOfSize:13]];
    }
}

這時候代碼調用 myWillMoveToSuperview 其實是調用的

  [self willMoveToSuperview:newSuperview];

然后接下來執行判斷等代碼。
這里面有很多彎不好繞,要靜下心好好捋一下。


2 消息轉發

//c語言的函數  Obj-C的方法(method)就是一個至少需要兩個參數(self,_cmd)的C函數
//Since the function must take at least two arguments—self and _cmd, the second and third characters must be “@:” (the first character is the return type).
void minus(id self,SEL _cmd,NSNumber *val){
    NSLog(@"%0.2f",[[self valueForKey:@"value"] floatValue] - [val floatValue]);
}


//第一步      沒有方法 添加方法實現
+ (BOOL)resolveInstanceMethod:(SEL)sel{
    if (sel == @selector(minus:)) {
        //v@:f     返回值為void  @: the second and third characters must be “@:”
        class_addMethod([self class], sel, (IMP) minus, "v@:f");
        return YES;
    }
    return [super resolveInstanceMethod:sel];
}

//第二步   指向新的方法接收者
- (id)forwardingTargetForSelector:(SEL)aSelector{
    if (aSelector == @selector(uppercaseString)) {
        return @"hello world";
    }
    return [super forwardingTargetForSelector:aSelector];
}

簡單介紹下消息轉發。輕松學習之一--Objective-C消息轉發


第一步,調用一個對象的方法,進入對象方法列表中尋找,找到執行。找不到進入父類尋找。直到找到,找不到進入下一步。


第二步,給開發者一個機會 動態的給對象添加一個方法去執行。若不處理進入下一步.


第三步,進入本步說明這個對象不處理此方法的調用,這時可以讓開發者指定一個能處理此方法的對象。形象的說明就是 這件事小明沒能力做,但任務已經派發了,他認為小剛能做,就把這個任務讓小剛去做。若不處理進入下一步。


第四步,進入這一步說明問題很大了,不過系統還是給開發者最后一個機會,重新指定一個人,指定一個任務,重新包裝一下去執行。就好像這件事沒人管沒人執行,但任務下來了,得找個應急的臨時工頂一下,隨便做點啥都行,讓領導知道有人干活就好。如果臨時工也沒有找,那肯定要出大事了。系統崩潰、閃退、報錯。


最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,908評論 6 541
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,324評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,018評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,675評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,417評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,783評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,779評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,960評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,522評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,267評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,471評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,009評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,698評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,099評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,386評論 1 294
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,204評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,436評論 2 378

推薦閱讀更多精彩內容

  • 目錄 Objective-C Runtime到底是什么 Objective-C的元素認知 Runtime詳解 應用...
    Ryan___閱讀 1,948評論 1 3
  • 這篇文章完全是基于南峰子老師博客的轉載 這篇文章完全是基于南峰子老師博客的轉載 這篇文章完全是基于南峰子老師博客的...
    西木閱讀 30,580評論 33 466
  • 轉至元數據結尾創建: 董瀟偉,最新修改于: 十二月 23, 2016 轉至元數據起始第一章:isa和Class一....
    40c0490e5268閱讀 1,755評論 0 9
  • Runtime是什么 Runtime 又叫運行時,是一套底層的 C 語言 API,其為 iOS 內部的核心之一,我...
    SuAdrenine閱讀 896評論 0 3
  • 一、Runtime簡介 Runtime簡稱運行時。OC就是運行時機制,也就是在運行時候的一些機制,其中最主要的是消...
    林安530閱讀 1,076評論 0 2