02 runtime用法之交換方法

1 方法調(diào)用機(jī)制

  • 本質(zhì)是讓對象發(fā)送消息.對象方法保存到類中,每個類都有一個方法列表
  • (1)根據(jù)對象的isa指針找到對應(yīng)的類
  • (2)根據(jù)方法編號查找到方法名
  • (3)根據(jù)方法名找到函數(shù)實(shí)現(xiàn),方法名就是函數(shù)入口

2 交換方法的實(shí)現(xiàn)機(jī)制

3 交換方法使用舉例

場景: 有個項(xiàng)目,已經(jīng)開發(fā)2年多了,之前加載圖片都是用UIImage,忽然有一天,老大說給我寫一個加載圖片方法,判斷是否成功加載圖片
常用思路:
  • (1)直接添加判斷
 // 1.加載圖片
    UIImage *image = [UIImage imageNamed:@"abc"];
    
    // 2.判斷
    if (image) {
        NSLog(@"加載成功");
    } else {
        NSLog(@"加載失敗");
    }
備注:封裝性不好,到處都需要寫判斷代碼
  • (2)分類中重寫系統(tǒng)的imageNamed(不推薦,會把系統(tǒng)方法覆蓋掉)

  • (3)自定義image
    創(chuàng)建一個繼承自UIImage的類,實(shí)現(xiàn)方法:

+ (UIImage *)imageNamed:(NSString *)name
{
    // 加載圖片
    // super:UIImage
    UIImage *image = [super imageNamed:name];
    
    if (image) {
        NSLog(@"加載成功");
    } else {
        NSLog(@"加載失敗");
    } 
    return image;
}

備注:只能在后期開發(fā)過程中使用,如果之前圖片加載的地方都要做判斷,需要把所有的UIImage換成自定義的MyImage,工作量大.
  • (4)runtime交換方法實(shí)現(xiàn)(推薦)
1.創(chuàng)建一個UIImage的分類,自定義my_imageNamed方法

+ (UIImage *)xmg_imageNamed:(NSString *)name
{
    // 1.加載圖片
    UIImage *image = [UIImage xmg_imageNamed:name];
    
    // 2.判斷
    if (image) {
        NSLog(@"加載成功");
    } else {
        NSLog(@"加載失敗");
    }
    return image;
}

 2. 在load方法中實(shí)現(xiàn)方法交換

// 保證在所有方法之前交換,只會調(diào)用一次
+ (void)load
{
    // 獲取imageName方法
    Method imageNamedMethod = class_getClassMethod(self, @selector(imageNamed:));
    
    // 獲取MY_imageNamed方法(自定義的方法)
    Method my_imageNamedMethod = class_getClassMethod(self, @selector(my_imageNamed:));
    
    // 利用runtime交換方法
 method_exchangeImplementations(imageNamedMethod, my_imageNamedMethod);
}
備注:交換以后,調(diào)用imageNamed方法,實(shí)質(zhì)實(shí)現(xiàn)的是my_imageNamed方法;調(diào)用my_imageNamed方法,實(shí)質(zhì)實(shí)現(xiàn)的是imageNamed方法;
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容