Runtime從零學(xué)起(一)

寫(xiě)在前邊的話(huà):打算開(kāi)始寫(xiě)個(gè)系列學(xué)習(xí)筆記,不喜勿噴?。。?!

由于項(xiàng)目需要,先學(xué)習(xí)了利用Runtime實(shí)現(xiàn)方法互換從而擴(kuò)充功能,學(xué)習(xí)中與類(lèi)目(分類(lèi))做了個(gè)對(duì)比,一并寫(xiě)出來(lái),看官勿怪....

Runtime的各種原理一搜一大堆,這里就不command+V了,直接上代碼

這個(gè)demo的目的是在利用name加載圖片后,獲取是否加載成功,不成功做些記錄或其他操作,給UIImage添加個(gè)分類(lèi)也很容易實(shí)現(xiàn),這次真的上代碼了

分類(lèi)實(shí)現(xiàn)

分類(lèi).h文件

@interface UIImage (LoadResult)

//先用類(lèi)別實(shí)現(xiàn) 給系統(tǒng)類(lèi)添加方法 缺點(diǎn):所有用到的地方都需要導(dǎo)入分類(lèi)的頭文件并且修改方法 如果是給已經(jīng)存在的項(xiàng)目擴(kuò)充某功能 能把”C“、“V”鍵給摁壞

+(UIImage *)imageWithName:(NSString *)name;

@end


分類(lèi).m文件

@implementation UIImage (LoadResult)

//用類(lèi)別實(shí)現(xiàn)

+(UIImage *)imageWithName:(NSString *)name {

? ? UIImage *image = [UIImage imageNamed:name];//原功能

? ? //新增功能

? ? if (image) {

? ? ? ? NSLog(@"圖片%@加載成功!",name);

? ? }else {

? ? ? ? NSLog(@"圖片%@加載失??!",name);

? ? }

? ? return image;

}

@end

分類(lèi)的使用:

#import "UIImage+LoadResult.h" //每個(gè)用到的地方都要導(dǎo)入 也可以放在.pch中

UIImageView *imageView1 = [[UIImageView alloc] init];

imageView1.image = [UIImage imageWithName:@"banner"];//只能用新的方法

[self.view addSubview:imageView1];

imageView1.sd_layout.leftSpaceToView(self.view, 20).rightSpaceToView(self.view, 20).topSpaceToView(self.view, 100).heightIs(80);

UIImageView *imageView2 = [[UIImageView alloc] init];

imageView2.image = [UIImage imageWithName:@"hahahabucunzai"];

[self.view addSubview:imageView2];

imageView2.sd_layout.leftSpaceToView(self.view, 20).rightSpaceToView(self.view, 20).topSpaceToView(imageView1, 80).heightIs(80);

打印結(jié)果:

OK,目的達(dá)成 接下來(lái),用Runtime將方法調(diào)換,沒(méi)錯(cuò)終于到正題了

Runtime實(shí)現(xiàn)

#import <objc/runtime.h> //導(dǎo)入runtime相關(guān)的類(lèi)

//load方法在加載分類(lèi)至內(nèi)存的時(shí)候調(diào)用 方法的交換要在消息傳遞之前

+(void)load {

? ? //獲取imageNamed方法實(shí)現(xiàn)地址

? ? Method imageNamed = class_getClassMethod(self, @selector(imageNamed:));

? ? //獲取imageWithName方法實(shí)現(xiàn)地址

? ? Method imageWithName = class_getClassMethod(self, @selector(imageWithName:));

? ? //交換imageNamed和imageWithName方法實(shí)現(xiàn)地址 從而達(dá)到實(shí)現(xiàn)交換方法實(shí)現(xiàn)的目的

? ? method_exchangeImplementations(imageNamed, imageWithName);

}

//實(shí)現(xiàn)用來(lái)替換imageNamed:的方法

+(UIImage *)imageWithName:(NSString *)name {

? ? //獲取照片 這個(gè)地方要調(diào)用imageWithName? 因?yàn)閕mageWithName和imageNamed已經(jīng)互換了 當(dāng)分類(lèi)加載至內(nèi)存的時(shí)候 這種交換關(guān)系就已經(jīng)確定了

? ? UIImage *image = [UIImage imageWithName:name];

? ? //添加功能

? ? if (image) {

? ? ? ? NSLog(@"圖片%@加載成功!",name);

? ? }else {

? ? ? ? NSLog(@"圖片%@加載失?。?,name);

? ? }

? ? return image;

}

加載圖片調(diào)用:

UIImageView *imageView1 = [[UIImageView alloc] init];

imageView1.image = [UIImage imageNamed:@"banner"];//這時(shí)候直接用imageNamed:

?[self.view addSubview:imageView1];

imageView1.sd_layout.leftSpaceToView(self.view, 20).rightSpaceToView(self.view, 20).topSpaceToView(self.view, 100).heightIs(KWidth/4.0);

UIImageView *imageView2 = [[UIImageView alloc] init];

imageView2.backgroundColor = [UIColor magentaColor];

imageView2.image = [UIImage imageNamed:@"hahahabucunzai"];

[self.view addSubview:imageView2];

imageView2.sd_layout.leftSpaceToView(self.view, 20).rightSpaceToView(self.view, 20).topSpaceToView(imageView1, 80).heightIs(KWidth/4.0);

打印結(jié)果:

上邊的是其他頁(yè)面用到的圖片,并未特意做操作,但也調(diào)用到了交換后的方法,就是這么隨意0.0

OK,到此結(jié)束!感謝諸位看官,歡迎指導(dǎo)交流。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀(guān)點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

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