寫(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)交流。