Runtime的簡(jiǎn)單使用

1.方法的交換使用
那么在什么情況下需要使用到這個(gè)呢,讓我來舉個(gè)栗子??,請(qǐng)看以下代碼,如果當(dāng)照片的名字是錯(cuò)誤的話或者為空的話我們并不能及時(shí)的知道呢
UIImage *image = [UIImage imageNamed:@"123"];
首先想到的處理辦法可能是,寫個(gè)UIImage的擴(kuò)充類別,就叫做UIImage+image吧,然后自己定義個(gè)方法進(jìn)行判斷,如下代碼:

+(UIImage *)dm_imageNamed:(NSString *)imageName{
    UIImage *image = [UIImage imageNamed:imageName];
    if (image == nil) {
        NSLog(@"加載image為空");
        return nil;
    }else{
        return image;
    }
}

可是每次調(diào)用上述代碼,都需要導(dǎo)入這個(gè)頭文件,會(huì)比較麻煩,這時(shí)候我們就可以用到runtime解決這個(gè)問題,我們可以將系統(tǒng)的imageNamed:和我們自己定義的dm_imageNamed:的方法進(jìn)行調(diào)換,即調(diào)用系統(tǒng)的方法就在調(diào)用自定義的方法.需要在分類中加入這個(gè)方法:

+(void)load{
    //記載這個(gè)分類的時(shí)候調(diào)用
    NSLog(@"*****%s",__func__);
    //獲取類方法
    //class_getClassMethod(<#__unsafe_unretained Class cls#>, <#SEL name#>)
    //獲取對(duì)象方法
    //class_getInstanceMethod(<#__unsafe_unretained Class cls#>, <#SEL name#>)
    
    //Class獲取哪個(gè)類的方法,SEL:獲取方法編號(hào),根據(jù)SEL就能去對(duì)應(yīng)的類找方法
    Method imageName = class_getClassMethod([UIImage class], @selector(imageNamed:));
    Method dm_imageName = class_getClassMethod([UIImage class], @selector(dm_imageNamed:));
    method_exchangeImplementations(imageName, dm_imageName);
}

這時(shí)候兩個(gè)方法就進(jìn)行互換了,注意,我們還需要將dm_imageNamed:的方法中改成下面這句,否則會(huì)造成循環(huán)引用.

UIImage *image = [UIImage dm_imageNamed:imageName];

這樣,我們就可以盡情的調(diào)用imageNamed:方法,實(shí)際上執(zhí)行的是dm_imageNamed:這個(gè)方法.

2.動(dòng)態(tài)添加方法(懶加載模式)
新建一個(gè)Person繼承于NSObject,我們?cè)赩C中執(zhí)行如下代碼,

Person *pp = [[Person alloc]init];
//performSelector:可以根據(jù)方法名找到對(duì)應(yīng)方法
 [pp performSelector:@selector(eat)];

動(dòng)態(tài)添加方法,首先要實(shí)現(xiàn)resolveClassMethod,當(dāng)調(diào)用了沒有實(shí)現(xiàn)的方法,那么就會(huì)走這個(gè)方法,當(dāng)然,方法沒有的話程序會(huì)崩潰的哦,所以打斷點(diǎn)看結(jié)果嘛.在Person.m文件寫入如下代碼:

+(BOOL)resolveInstanceMethod:(SEL)sel{
    if (sel == @selector(eat)) {
        //打印出的就是eat這個(gè)方法
          NSLog(@"%@",NSStringFromSelector(sel));
        return YES;
    }
    return YES;
}

接下來就說說用runtime如何動(dòng)態(tài)實(shí)現(xiàn),我們這里以一個(gè)可以傳入?yún)?shù)的函數(shù)為栗子??

+(BOOL)resolveInstanceMethod:(SEL)sel{
    if (sel == @selector(eat:)) {
        NSLog(@"啦啦啦啦");
        /*class_addMethod(Class cls, SEL name, IMP imp, 
                                 const char *types) 
         參數(shù)分別對(duì)應(yīng):給哪個(gè)類添加方法; 添加方法的編號(hào)是什么;方法的實(shí)現(xiàn),函數(shù)的入口,即指針;方法類型)
         */
        class_addMethod(self, sel, eat, "v@:@");
        return YES;
    }
    return YES;
}

其中方法類型這項(xiàng)我們可以參考官方文檔

runtime.png

我們可以看到V@:@就代表一個(gè)有參無返回的函數(shù).接下來我們需要實(shí)現(xiàn)這個(gè)函數(shù),并且可以調(diào)用[pp performSelector:@selector(eat:) withObject:@1111]的方法對(duì)結(jié)果進(jìn)行分析.

void eat(id self,SEL _cmd,id param){
//其中參數(shù)(id,SEL),調(diào)用方法,系統(tǒng)會(huì)默認(rèn)傳入這個(gè)隱式參數(shù)
 NSLog(@"%@,%@",param,NSStringFromSelector(_cmd));
}

3.動(dòng)態(tài)方法添加屬性
當(dāng)我們創(chuàng)建一個(gè)分類,并且給分類添加屬性,進(jìn)行相應(yīng)的調(diào)用(catagory本來就不能為原有類添加屬性, 只能添加方法),我們可以通過runtime進(jìn)行屬性綁定,我們創(chuàng)建一個(gè)類別并且申明@property (nonatomic, strong) NSString *name接下來重寫set和get方法實(shí)現(xiàn).

-(void)setName:(NSString *)name{
    /*
        參數(shù)分別對(duì)應(yīng):給某個(gè)對(duì)象添加屬性;屬性名,根據(jù)key去獲取關(guān)聯(lián)的對(duì)象;關(guān)聯(lián)的值;策略(這里是傳入字符串)
     */
    objc_setAssociatedObject(self,@"name", name, OBJC_ASSOCIATION_RETAIN);
}
-(NSString *)name{
    return objc_getAssociatedObject(self, @"name");
}

第一次寫,有不足的地方歡迎指正呢.我也在學(xué)習(xí)runtime中嘞.歡迎交流哦!
以上??

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

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

  • Runtime簡(jiǎn)介 Runtime簡(jiǎn)稱運(yùn)行時(shí),是一套比較底層的純C語(yǔ)言的API, 作為OC的核心,運(yùn)行時(shí)是一種面向...
    Mark_Guan閱讀 560評(píng)論 0 6
  • runtime簡(jiǎn)介 RunTime簡(jiǎn)稱運(yùn)行時(shí)。OC就是運(yùn)行時(shí)機(jī)制,也就是在運(yùn)行時(shí)候的一些機(jī)制,其中最主要的是消息機(jī)...
    芝麻綠豆閱讀 533評(píng)論 3 6
  • 對(duì)于從事 iOS 開發(fā)人員來說,所有的人都會(huì)答出【runtime 是運(yùn)行時(shí)】什么情況下用runtime?大部分人能...
    夢(mèng)夜繁星閱讀 3,732評(píng)論 7 64
  • 一、runtime簡(jiǎn)介 1.RunTime簡(jiǎn)稱運(yùn)行時(shí)。OC就是運(yùn)行時(shí)機(jī)制,也就是在運(yùn)行時(shí)候的一些機(jī)制,其中最主要的...
    踐行者_(dá)Leng閱讀 262評(píng)論 0 0
  • 躲到你溫暖的臂彎里 今天在地鐵上,看到兩對(duì)夫妻。 其中一對(duì)夫妻,好想是要搬家的緣故,老公扛了大大小小的行李,吃力的...
    迷糊趙小妖閱讀 506評(píng)論 0 0