轉:Runtime的使用

一、交換兩個方法的實現(xiàn)既忆,攔截系統(tǒng)自帶的方法調用功能

需要用到的方法 <objc/runtime.h>
獲得某個類的類方法
Method class_getClassMethod(Class cls , SEL name)
獲得某個類的實例對象方法
Method class_getInstanceMethod(Class cls , SEL name)
交換兩個方法的實現(xiàn)
void method_exchangeImplementations(Method m1 , Method m2)

案例1:方法簡單的交換

創(chuàng)建一個Person類柠座,類中實現(xiàn)以下兩個類方法邑雅,并在.h 文件中聲明

+ (void)run {
    NSLog(@"跑");
}

+ (void)study {
    NSLog(@"學習");
}

控制器中調用,則先打印跑妈经,后打印學習

[Person run];
[Person study];

下面通過runtime 實現(xiàn)方法交換淮野,類方法用class_getClassMethod ,對象方法用class_getInstanceMethod

// 獲取兩個類的類方法
Method m1 = class_getClassMethod([Person class], @selector(run));
Method m2 = class_getClassMethod([Person class], @selector(study));
// 開始交換方法實現(xiàn)
method_exchangeImplementations(m1, m2);
// 交換后吹泡,先打印學習骤星,再打印跑!
[Person run];
[Person study];

案例2:攔截系統(tǒng)方法

需求:比如iOS6 升級 iOS7 后需要版本適配爆哑,根據(jù)不同系統(tǒng)使用不同樣式圖片(擬物化和扁平化)洞难,如何通過不去手動一個個修改每個UIImage的imageNamed:方法就可以實現(xiàn)為該方法中加入版本判斷語句?

步驟:
1揭朝、為UIImage建一個分類(UIImage+Category)
2队贱、在分類中實現(xiàn)一個自定義方法流强,方法中寫要在系統(tǒng)方法中加入的語句挥转,比如版本判斷

+ (UIImage *)xh_imageNamed:(NSString *)name {
    double version = [[UIDevice currentDevice].systemVersion doubleValue];
    if (version >= 7.0) {
        // 如果系統(tǒng)版本是7.0以上,使用另外一套文件名結尾是‘_os7’的扁平化圖片
        name = [name stringByAppendingString:@"_os7"];
    }
    return [UIImage xh_imageNamed:name];
}

3、分類中重寫UIImage的load方法为严,實現(xiàn)方法的交換(只要能讓其執(zhí)行一次方法交換語句明郭,load再合適不過了)

+ (void)load {
    // 獲取兩個類的類方法
    Method m1 = class_getClassMethod([UIImage class], @selector(imageNamed:));
    Method m2 = class_getClassMethod([UIImage class], @selector(xh_imageNamed:));
    // 開始交換方法實現(xiàn)
    method_exchangeImplementations(m1, m2);
}

注意:自定義方法中最后一定要再調用一下系統(tǒng)的方法谅畅,讓其有加載圖片的功能谱煤,但是由于方法交換,系統(tǒng)的方法名已經(jīng)變成了我們自定義的方法名(有點繞嘉抓,就是用我們的名字能調用系統(tǒng)的方法索守,用系統(tǒng)的名字能調用我們的方法),這就實現(xiàn)了系統(tǒng)方法的攔截抑片!
利用以上思路卵佛,我們還可以給 NSObject 添加分類,統(tǒng)計創(chuàng)建了多少個對象蓝丙,給控制器添加分類级遭,統(tǒng)計有創(chuàng)建了多少個控制器,特別是公司需求總變的時候渺尘,在一些原有控件或模塊上添加一個功能挫鸽,建議使用該方法!

二鸥跟、在分類中設置屬性丢郊,給任何一個對象設置屬性

眾所周知,分類中是無法設置屬性的医咨,如果在分類的聲明中寫@property 只能為其生成get 和 set 方法的聲明枫匾,但無法生成成員變量,就是雖然點語法能調用出來拟淮,但程序執(zhí)行后會crash干茉,有人會想到使用全局變量呢?比如這樣

int _age;

- (int )age {
    return _age;
}

- (void)setAge:(int)age {
    _age = age;
}

但是全局變量程序整個執(zhí)行過程中內存中只有一份很泊,我們創(chuàng)建多個對象修改其屬性值都會修改同一個變量角虫,這樣就無法保證像屬性一樣每個對象都擁有其自己的屬性值。這時我們就需要借助runtime為分類增加屬性的功能了

需要用到的方法 <objc/runtime.h>

set方法委造,將值value 跟對象object 關聯(lián)起來(將值value 存儲到對象object 中)
參數(shù) object:給哪個對象設置屬性
參數(shù) key:一個屬性對應一個Key戳鹅,將來可以通過key取出這個存儲的值,key 可以是任何類型:double昏兆、int 等枫虏,建議用char 可以節(jié)省字節(jié)
參數(shù) value:給屬性設置的值
參數(shù)policy:存儲策略 (assign 、copy 、 retain就是strong)
void objc_setAssociatedObject(id object , const void *key ,id value ,objc_AssociationPolicy policy)

利用參數(shù)key 將對象object中存儲的對應值取出來
id objc_getAssociatedObject(id object , const void *key)

步驟:

1隶债、創(chuàng)建一個分類腾它,比如給任何一個對象都添加一個name屬性,就是NSObject添加分類(NSObject+Category)
2燃异、先在.h 中@property 聲明出get 和 set 方法携狭,方便點語法調用

@property(nonatomic,copy)NSString *name;

3继蜡、在.m 中重寫set 和 get 方法回俐,內部利用runtime 給屬性賦值和取值

char nameKey;

- (void)setName:(NSString *)name {
    // 將某個值跟某個對象關聯(lián)起來,將某個值存儲到某個對象中
    objc_setAssociatedObject(self, &nameKey, name, OBJC_ASSOCIATION_COPY_NONATOMIC);
}

- (NSString *)name {
    return objc_getAssociatedObject(self, &nameKey);
}
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末稀并,一起剝皮案震驚了整個濱河市仅颇,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌碘举,老刑警劉巖忘瓦,帶你破解...
    沈念sama閱讀 218,386評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異引颈,居然都是意外死亡耕皮,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,142評論 3 394
  • 文/潘曉璐 我一進店門蝙场,熙熙樓的掌柜王于貴愁眉苦臉地迎上來凌停,“玉大人,你說我怎么就攤上這事售滤》D猓” “怎么了?”我有些...
    開封第一講書人閱讀 164,704評論 0 353
  • 文/不壞的土叔 我叫張陵完箩,是天一觀的道長赐俗。 經(jīng)常有香客問我,道長弊知,這世上最難降的妖魔是什么阻逮? 我笑而不...
    開封第一講書人閱讀 58,702評論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮秩彤,結果婚禮上叔扼,老公的妹妹穿的比我還像新娘。我一直安慰自己呐舔,他們只是感情好币励,可當我...
    茶點故事閱讀 67,716評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著珊拼,像睡著了一般食呻。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,573評論 1 305
  • 那天仅胞,我揣著相機與錄音每辟,去河邊找鬼。 笑死干旧,一個胖子當著我的面吹牛渠欺,可吹牛的內容都是我干的。 我是一名探鬼主播椎眯,決...
    沈念sama閱讀 40,314評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼挠将,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了编整?” 一聲冷哼從身側響起舔稀,我...
    開封第一講書人閱讀 39,230評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎掌测,沒想到半個月后内贮,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,680評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡汞斧,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,873評論 3 336
  • 正文 我和宋清朗相戀三年夜郁,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片粘勒。...
    茶點故事閱讀 39,991評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡竞端,死狀恐怖,靈堂內的尸體忽然破棺而出仲义,到底是詐尸還是另有隱情婶熬,我是刑警寧澤,帶...
    沈念sama閱讀 35,706評論 5 346
  • 正文 年R本政府宣布埃撵,位于F島的核電站赵颅,受9級特大地震影響,放射性物質發(fā)生泄漏暂刘。R本人自食惡果不足惜饺谬,卻給世界環(huán)境...
    茶點故事閱讀 41,329評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望谣拣。 院中可真熱鬧募寨,春花似錦、人聲如沸森缠。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,910評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽贵涵。三九已至列肢,卻和暖如春恰画,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背瓷马。 一陣腳步聲響...
    開封第一講書人閱讀 33,038評論 1 270
  • 我被黑心中介騙來泰國打工拴还, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人欧聘。 一個月前我還...
    沈念sama閱讀 48,158評論 3 370
  • 正文 我出身青樓片林,卻偏偏與公主長得像,于是被迫代替她去往敵國和親怀骤。 傳聞我的和親對象是個殘疾皇子费封,可洞房花燭夜當晚...
    茶點故事閱讀 44,941評論 2 355

推薦閱讀更多精彩內容

  • 轉至元數(shù)據(jù)結尾創(chuàng)建: 董瀟偉,最新修改于: 十二月 23, 2016 轉至元數(shù)據(jù)起始第一章:isa和Class一....
    40c0490e5268閱讀 1,715評論 0 9
  • 對于從事 iOS 開發(fā)人員來說晒喷,所有的人都會答出【runtime 是運行時】什么情況下用runtime?大部分人能...
    夢夜繁星閱讀 3,721評論 7 64
  • 這篇文章完全是基于南峰子老師博客的轉載 這篇文章完全是基于南峰子老師博客的轉載 這篇文章完全是基于南峰子老師博客的...
    西木閱讀 30,558評論 33 466
  • 女人對于購物的欲望果然都是相通的孝偎,人魚也不例外。 剛剛到了女性賣場凉敲,各式各樣的衣服便引起了魚小姐的一陣驚呼,搞得旁...
    紅霉素閱讀 678評論 0 9
  • 最近玩豆瓣寺旺,加了個交筆友的小組爷抓,找回了關于書信的種種回憶∽杷埽看到《給某某的一封信》蓝撇,立馬想起了三等獎小姐寫過的信。那...
    美食偵探卡卡閱讀 303評論 0 0