runtime 學(xué)習(xí) 交叉方法(動(dòng)態(tài)適配UIimageView的圖像)

前言: 本章節(jié)是對(duì)上一章節(jié)的延伸,上一章對(duì)runtime的運(yùn)行機(jī)制沒做過多的解釋软啼,其一:我也是在學(xué)習(xí)了解過程中榛瓮,說白了也就是小白航背,只能寫一些我知道我理解的東西喉悴,其二:網(wǎng)上各個(gè)論壇以及網(wǎng)站都有一些大牛們的非常好的文章可以供大家參考閱讀。

交叉方法:
再次啰嗦一下他的作用和使用目的玖媚,它主要是用來替換系統(tǒng)的方法箕肃,當(dāng)然不是完全替換,底層的東西最好不要輕易修改今魔,那這里的交換對(duì)于大部分人來說就是在調(diào)用系統(tǒng)方法之前插入自己的方法勺像,然后再通過自己的方法調(diào)用原來系統(tǒng)的方法,以便達(dá)到自己的目的错森。

下面是通過交叉方法替換UIImageVIew的setIamge:方法做一些事情吟宦,具體是什么事情呢

大家在使用UIimageView的時(shí)候有些時(shí)候不得已需要設(shè)置ImageView的Frame然而在在得到set圖片的時(shí)候,圖片的大小和imageview的大小并不是一樣大的涩维,這就會(huì)產(chǎn)生拉伸殃姓,消耗性能,特別是在TableView快速滾動(dòng)的時(shí)候瓦阐,影響性能蜗侈,這個(gè)事例就是利用runtime機(jī)制來優(yōu)化ImageView

擴(kuò)展:加載頭像后 點(diǎn)擊——模擬器——點(diǎn)擊Debug——ColorMilasignedimages——> 頭像上面如果覆蓋了一層黃色的 說明圖像有所拉伸


08579A4C-45B5-423F-A517-6A0BA925776D.png
 - (void)viewDidLoad {
    [super viewDidLoad];
    
    self.view.backgroundColor =[UIColor redColor];
 
    UIImageView * imageview =[[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 200, 200)];
    
    imageview.center = self.view.center;
    
    imageview.image =[UIImage imageNamed:@"icon-120.png"];
    
    [self.view  addSubview:imageview];
    // 目標(biāo) 在設(shè)置頭像的時(shí)候 攔截系統(tǒng)方法對(duì)頭像做一些事情


    
    //例 AFN 中在AFNURLSessionManger類中 有一個(gè)af_resume,af_suspend 的方法中使用了內(nèi)聯(lián)函數(shù)交換了resume睡蟋,suspend 目的是為了替換系統(tǒng)的方法在之前 發(fā)一個(gè)通知監(jiān)聽網(wǎng)絡(luò)狀態(tài)(發(fā)起踏幻,和掛起監(jiān)聽)}  ```

import <UIKit/UIKit.h>

@interface UIImageView (XW_SetFrame)
-(void)xw_setimage:(UIImage *)image;

@end```

#import "UIImageView+XW_SetFrame.h"
#import <objc/runtime.h>

/*
 AFN 中AFNURLSessionManager中 static inline void af_swizzleSelector 可找到
 Method originalMethod = class_getInstanceMethod(theClass, originalSelector);
 Method swizzledMethod = class_getInstanceMethod(theClass, swizzledSelector);
 method_exchangeImplementations(originalMethod, swizzledMethod);
 
 */
@implementation UIImageView (XW_SetFrame)





// 當(dāng)系統(tǒng)加載運(yùn)行時(shí)的時(shí)候會(huì)調(diào)用的方法 在這里做交換方法
+(void)load
{
    // 獲取 UIimageview 類的實(shí)力方法:setImage
    Method originalMethod = class_getInstanceMethod([self class], @selector(setImage:));
    //獲取 UIimageview 類的實(shí)力方法:xw_setimage
    Method swizzledMethod = class_getInstanceMethod([self class], @selector(xw_setimage:));
    // 交換
    method_exchangeImplementations(originalMethod, swizzledMethod);

}

// 當(dāng)系統(tǒng)在調(diào)用Imageview的setimage的時(shí)候自動(dòng)調(diào)用我們的xw_setimage
-(void)xw_setimage:(UIImage *)image
{
    NSLog(@"%s",__FUNCTION__);
    
    // 根據(jù)imageview的大小生成一張和imageview大小相同的圖片
    
    /*
     
     self.bounds.size :繪制大小
     
     yes:不touming
     0:使用屏幕分辨率 自動(dòng)適配
     
     
     */
    UIGraphicsBeginImageContextWithOptions(self.bounds.size, YES, 0);
    
    // 繪制
    
    [image drawInRect:self.bounds];
    
    //      取得結(jié)果
    
    UIImage *result = UIGraphicsGetImageFromCurrentImageContext();
    
    //關(guān)閉上下文
    
    UIGraphicsEndImageContext();
    
    // 交換后 調(diào)用setimage 相當(dāng)于調(diào)用xw_setimage
    //調(diào)用xw_setimage相當(dāng)于調(diào)用setimage
    [self xw_setimage:result];//也就是說這句是調(diào)用系統(tǒng)的setimage
}
@end```
![7EC02E4E-AD18-417C-B7FA-D788CD139F7F.png](http://upload-images.jianshu.io/upload_images/1460277-41cbcd9f8eb1bf0d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)


但是在后來發(fā)現(xiàn)使用交叉方法直接替換底層的setimge:會(huì)帶來一系列問題,主要原因是這種替換將會(huì)導(dǎo)致所有的UIimageView以及繼承UIimageView的類都會(huì)發(fā)生剪切薄湿,這就導(dǎo)致一些沒有設(shè)置Frame的也發(fā)生重繪叫倍,然而這地方繪制所取的區(qū)域是self.bounds,self.bounds  因?yàn)闆]有設(shè)置又為0,就會(huì)產(chǎn)生圖片不能顯示豺瘤,我在這地方加上判斷,如果判斷self.bounds設(shè)置過了听诸,才執(zhí)行剪切坐求,沒有設(shè)置就不進(jìn)行剪切,解決問題如下:

-(void)xw_setimage:(UIImage *)image
{
NSLog(@"%s",FUNCTION);

// 根據(jù)imageview的大小生成一張和imageview大小相同的圖片

/*
 
 self.bounds.size :繪制大小
 
 yes:不touming
 0:使用屏幕分辨率 自動(dòng)適配
 
 
 */
if (self.bounds.size.width==0||self.bounds.size.height==0) {
    
     [self xw_setimage:image];//也就是說這句是調(diào)用系統(tǒng)的setimage
}
else
{
UIGraphicsBeginImageContextWithOptions(self.bounds.size, YES, 0);

// 繪制

[image drawInRect:self.bounds];

//      取得結(jié)果

UIImage *result = UIGraphicsGetImageFromCurrentImageContext();

//關(guān)閉上下文

UIGraphicsEndImageContext();

if (self.bounds.size.width==0||self.bounds.size.height==0) {
    
    [self xw_setimage:image];
}
else
{
// 交換后 調(diào)用setimage 相當(dāng)于調(diào)用xw_setimage
//調(diào)用xw_setimage相當(dāng)于調(diào)用setimage
[self xw_setimage:result];//也就是說這句是調(diào)用系統(tǒng)的setimage
}
}

}```

然而問題并不止,尼瑪各個(gè)各個(gè)框架的Gif圖不能播放晌梨,也就意味著這個(gè)優(yōu)化模式不能用了桥嗤,交叉方法是這樣的使的,要想優(yōu)化只能繼承UIimageView 重寫setimage:方法在里面這個(gè)方法里面做圖片重繪仔蝌,保證獨(dú)立性

#import "XWImageView.h"

@implementation XWImageView


-(void)setImage:(UIImage *)image
{
    
    NSLog(@"%s",__FUNCTION__);
    

    
    UIGraphicsBeginImageContextWithOptions(self.bounds.size, YES, 0);
    
    // 繪制
    
    [image drawInRect:self.bounds];
    
    //      取得結(jié)果
    
    UIImage *result = UIGraphicsGetImageFromCurrentImageContext();
    
    //關(guān)閉上下文
    
    UIGraphicsEndImageContext();
    
    
    [super setImage:result];
}

@end```

同時(shí)也在尋求解決辦法泛领,歡迎大家提意見
#下一章待續(xù) 通過交叉方法實(shí)現(xiàn)右滑pop到上一個(gè)控制器
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市敛惊,隨后出現(xiàn)的幾起案子渊鞋,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,744評(píng)論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件锡宋,死亡現(xiàn)場離奇詭異儡湾,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)执俩,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,505評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門徐钠,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人役首,你說我怎么就攤上這事尝丐。” “怎么了衡奥?”我有些...
    開封第一講書人閱讀 163,105評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵摊崭,是天一觀的道長。 經(jīng)常有香客問我杰赛,道長呢簸,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,242評(píng)論 1 292
  • 正文 為了忘掉前任乏屯,我火速辦了婚禮根时,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘辰晕。我一直安慰自己蛤迎,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,269評(píng)論 6 389
  • 文/花漫 我一把揭開白布含友。 她就那樣靜靜地躺著替裆,像睡著了一般。 火紅的嫁衣襯著肌膚如雪窘问。 梳的紋絲不亂的頭發(fā)上辆童,一...
    開封第一講書人閱讀 51,215評(píng)論 1 299
  • 那天,我揣著相機(jī)與錄音惠赫,去河邊找鬼把鉴。 笑死,一個(gè)胖子當(dāng)著我的面吹牛儿咱,可吹牛的內(nèi)容都是我干的庭砍。 我是一名探鬼主播,決...
    沈念sama閱讀 40,096評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼混埠,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼怠缸!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起钳宪,我...
    開封第一講書人閱讀 38,939評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤揭北,失蹤者是張志新(化名)和其女友劉穎扳炬,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體罐呼,經(jīng)...
    沈念sama閱讀 45,354評(píng)論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡鞠柄,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,573評(píng)論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了嫉柴。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片厌杜。...
    茶點(diǎn)故事閱讀 39,745評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖计螺,靈堂內(nèi)的尸體忽然破棺而出夯尽,到底是詐尸還是另有隱情,我是刑警寧澤登馒,帶...
    沈念sama閱讀 35,448評(píng)論 5 344
  • 正文 年R本政府宣布匙握,位于F島的核電站,受9級(jí)特大地震影響陈轿,放射性物質(zhì)發(fā)生泄漏圈纺。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,048評(píng)論 3 327
  • 文/蒙蒙 一麦射、第九天 我趴在偏房一處隱蔽的房頂上張望蛾娶。 院中可真熱鬧,春花似錦潜秋、人聲如沸蛔琅。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,683評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽罗售。三九已至,卻和暖如春钩述,著一層夾襖步出監(jiān)牢的瞬間寨躁,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,838評(píng)論 1 269
  • 我被黑心中介騙來泰國打工切距, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留朽缎,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,776評(píng)論 2 369
  • 正文 我出身青樓谜悟,卻偏偏與公主長得像,于是被迫代替她去往敵國和親北秽。 傳聞我的和親對(duì)象是個(gè)殘疾皇子葡幸,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,652評(píng)論 2 354

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

  • 在iOS中隨處都可以看到絢麗的動(dòng)畫效果,實(shí)現(xiàn)這些動(dòng)畫的過程并不復(fù)雜贺氓,今天將帶大家一窺iOS動(dòng)畫全貌蔚叨。在這里你可以看...
    F麥子閱讀 5,110評(píng)論 5 13
  • 在iOS中隨處都可以看到絢麗的動(dòng)畫效果,實(shí)現(xiàn)這些動(dòng)畫的過程并不復(fù)雜,今天將帶大家一窺ios動(dòng)畫全貌蔑水。在這里你可以看...
    每天刷兩次牙閱讀 8,485評(píng)論 6 30
  • 本文轉(zhuǎn)載自:http://www.cocoachina.com/ios/20150106/10840.html 為...
    idiot_lin閱讀 637評(píng)論 0 1
  • *7月8日上午 N:Block :跟一個(gè)函數(shù)塊差不多邢锯,會(huì)對(duì)里面所有的內(nèi)容的引用計(jì)數(shù)+1,想要解決就用__block...
    炙冰閱讀 2,485評(píng)論 1 14
  • 在第13章“高效繪圖”中搀别,我們研究了和Core Graphics繪圖相關(guān)的性能問題丹擎,以及如何修復(fù)。和繪圖性能相關(guān)緊...
    雪_晟閱讀 629評(píng)論 0 0