Runtime看這個好懂,還全

Runtime講解

1. Runtime簡介

RunTime簡稱運行時。OC就是運行時機制,也就是在運行時候的一些機制,其中最主要的是消息機制。
對于C語言,函數(shù)的調(diào)用在編譯的時候會決定調(diào)用哪個函數(shù)
對于OC的函數(shù),屬于動態(tài)調(diào)用過程,在編譯的時候并不能決定真正調(diào)用哪個函數(shù),只有在真正運行的時候才會根據(jù)函數(shù)的名稱找到對應的函數(shù)來調(diào)用。
事實證明:
在編譯階段,OC可以調(diào)用任何函數(shù),即使這個函數(shù)并未實現(xiàn),只要聲明過就不會報錯。
在編譯階段,C語言調(diào)用未實現(xiàn)的函數(shù)就會報錯。

2.Runtime作用

Runtime作用之發(fā)送消息

方法調(diào)用的本質(zhì),就是讓對象發(fā)送消息。
objc_msgSend,只有對象才能發(fā)送消息,因此以objc開頭.
使用消息機制前提,必須導入#import <objc/message.h>
消息機制簡單使用
消息機制原理:對象根據(jù)方法編號SEL去映射表查找對應的方法實現(xiàn)

  • 簡單舉個例子
發(fā)送消息.png

runtime作用之交換方法

開發(fā)使用場景:系統(tǒng)自帶的方法功能不夠,給系統(tǒng)自帶的方法擴展一些功能,并且保持原有的功能。
方式一:繼承系統(tǒng)的類,重寫方法.
方式二:使用runtime,交換方法.
方式三:使用分類category


下面是對交換方法的使用---runtime修改系統(tǒng)viewWillAppear方法


無標題.png
  • 先看圖,下面解釋為啥這么寫???
無標題.png
  • 注意看這個斷點,是不是,沒走系統(tǒng)方法,交換了吧-----
無標題.png
  • 下面把代碼貼一下,方便自己與大家copy
    //由于交換方法我們希望在工程運行期間只執(zhí)行一次,所以通常寫在load里面
+ (void)load {
    Class class = [self class];
    
    SEL originalSelector = @selector(viewWillAppear:);
    SEL swizzledSelector = @selector(dgviewWillAppear:);
    
    Method originalMethod = class_getInstanceMethod(class, originalSelector);
    Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);
    
    BOOL success = class_addMethod(class, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod));
    if (success) {
        class_replaceMethod(class, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod));
    } else {
        method_exchangeImplementations(originalMethod, swizzledMethod);
    }

}

簡寫

+ (void)load {  
    Method imageMethodNamed = class_getClassMethod(self, @selector(imageNamed:));  
    Method myImageMethodNamed = class_getClassMethod(self, @selector(myImageNamed:));  
    //實現(xiàn)兩個方法的交換  
    method_exchangeImplementations(myImageMethodNamed,imageMethodNamed);  
} 

3runtime作用之動態(tài)添加方法

開發(fā)使用場景:如果一個類方法非常多,加載類到內(nèi)存的時候也比較耗費資源,需要給每個方法生成映射表,可以使用動態(tài)給某個類,添加方法解決。
經(jīng)典面試題:有沒有使用performSelector,其實主要想問你有沒有動態(tài)添加過方法

無標題.png

動態(tài)方法實現(xiàn)eat,Person.h是不用申明eat方法的,但是如果Person.m中不實現(xiàn)這個方法,編譯通過,執(zhí)行報錯unrecognized selector sent to instance


performSelector調(diào)用和直接調(diào)用的區(qū)別

前者執(zhí)行的方法是不需要在.h中聲明的,編譯過程絕對通過,但是如果調(diào)用該方法的類中沒有實
現(xiàn)該方法,執(zhí)行過程中會出現(xiàn)crash
后者直接調(diào)用,所調(diào)用的方法在.h中必須聲明,否則編譯都不能通過,并且與上面方法一樣,
如果執(zhí)行過程中發(fā)現(xiàn)沒有實現(xiàn)該方法,執(zhí)行過程中會出現(xiàn)crash

4Runtime之屬性綁定


就是將數(shù)據(jù)綁定到手勢對象上,然后在點擊的時候,從手勢對象上取數(shù)據(jù)

for (int i = 0; i < _roomInfo.rec_goods.count; i++) {
            RoomRecgoodInfo *recgoodInfo = _roomInfo.rec_goods[i];
            UIImageView *hotGoodImage = [[UIImageView alloc] initWithFrame:CGRectMake(i*(hotGoodImageH+12), 0, hotGoodImageH, hotGoodImageH)];
            hotGoodImage.layer.masksToBounds = YES;
            hotGoodImage.layer.cornerRadius = 5;
            hotGoodImage.userInteractionEnabled = YES;
            [hotGoodImage sd_setImageWithURL:[NSURL URLWithString:recgoodInfo.cover] placeholderImage:GOODSDEFAULTImge];
            
            UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapHotGoods:)];
            [hotGoodImage addGestureRecognizer:tap];
            [scroller addSubview:hotGoodImage];
            
            //runtime將數(shù)據(jù)綁定到該view之上
            objc_setAssociatedObject(tap, @"recgoodInfo", recgoodInfo, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
            
            UILabel *priceLab = [[UILabel alloc] initWithFrame:CGRectMake(X(hotGoodImage), MaxY(hotGoodImage), WIDTH(hotGoodImage), 35)];
            priceLab.textColor = [UIColor colorWithHexString:@"#FF0707"];
            priceLab.textAlignment = NSTextAlignmentCenter;
            priceLab.font = [UIFont systemFontOfSize:16];
            priceLab.text = [NSString stringWithFormat:@"¥%@",recgoodInfo.price];
            [scroller addSubview:priceLab];

        }


//點擊熱銷商品,去往商品詳情
- (void)tapHotGoods:(UITapGestureRecognizer *)tap {
    RoomRecgoodInfo *recgoodInfo = objc_getAssociatedObject(tap, @"recgoodInfo");
    GoodsDetailController *vc = [GoodsDetailController new];
    vc.goodsId = recgoodInfo.goods_id;
    vc.isPublishGoodsVC = YES;
    
    //創(chuàng)建直播小窗口
    [self createLiveWindow];
    
    UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:vc];
    [self presentViewController:nav animated:YES completion:nil];

    
}

5Runtime實現(xiàn)模型轉(zhuǎn)換

  1. 字典轉(zhuǎn)模型介紹
    現(xiàn)在的ios開發(fā)中,我們通常會使用MVC模式。當我們拿到數(shù)據(jù)的時候,我們要把數(shù)據(jù)轉(zhuǎn)成模型使用。
    2.字典轉(zhuǎn)模型的好處:
    (1)降低代碼的耦合度
    (2)所有字典轉(zhuǎn)模型部分的代碼統(tǒng)一集中在一處處理,降低代碼出錯的幾率
    (3)在程序中直接使用模型的屬性操作,提高編碼效率
    (4)調(diào)用方不用關(guān)心模型內(nèi)部的任何處理細節(jié)
  1. 利用runtime實現(xiàn)轉(zhuǎn)換:
    通過動態(tài)獲取屬性列表,然后取出屬性,由屬性在數(shù)據(jù)字典獲取值,然后在賦值給該模型屬性。當對象的屬性很少的時候,直接字典取出對應屬性值簡單賦值即可。
無標題.png
無標題.png
無標題.png
![無標題.png](http://upload-images.jianshu.io/upload_images/1398395-88e64d369492e0cf.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
![無標題.png](http://upload-images.jianshu.io/upload_images/1398395-103f9fb266f54677.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

以上是有問題的例子


無標題.png

這就對了吧,不怕模型轉(zhuǎn)換的時候出現(xiàn)key對不上,導致的問題了吧。

以上就是常用的一些runtime概念,其實平時我們不太會用這個。畢竟現(xiàn)在用這個的東西都有現(xiàn)成的三方庫。。。。不過還是了解一下好,這個代碼的世界還是很神奇的不是!!停筆!!!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

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

  • 對于從事 iOS 開發(fā)人員來說,所有的人都會答出【runtime 是運行時】什么情況下用runtime?大部分人能...
    夢夜繁星閱讀 3,734評論 7 64
  • 轉(zhuǎn)至元數(shù)據(jù)結(jié)尾創(chuàng)建: 董瀟偉,最新修改于: 十二月 23, 2016 轉(zhuǎn)至元數(shù)據(jù)起始第一章:isa和Class一....
    40c0490e5268閱讀 1,789評論 0 9
  • 這篇文章完全是基于南峰子老師博客的轉(zhuǎn)載 這篇文章完全是基于南峰子老師博客的轉(zhuǎn)載 這篇文章完全是基于南峰子老師博客的...
    西木閱讀 30,643評論 33 466
  • 股神沃倫·巴菲特今年已經(jīng) 87 歲,他應該是這個世界上最成功的投資者,他從白手起家開始做起,是伯克希爾·哈撒韋公司...
    雷宗揚閱讀 6,876評論 0 5
  • 出錯: 在使用Virtualbox的時候,有時候我們需要更新,但是更新后,發(fā)現(xiàn)程序啟動不了。這是由于程序更新導致W...
    王寶花閱讀 3,391評論 0 1