iOS runtime詳解一

RunTime是什么本缠?

眾所周知OC是一門高級編程語言,也是一門動態(tài)語言。有動態(tài)語言那也就有靜態(tài)語言,靜態(tài)語言---編譯階段就要決定調(diào)用哪個函數(shù)宴胧,如果函數(shù)未實現(xiàn)就會編譯報錯。如C語言表锻。動態(tài)語言---編譯階段并不能決定真正調(diào)用哪個函數(shù)恕齐,只要函數(shù)聲明過即使沒有實現(xiàn)也不會報錯。如OC語言瞬逊。

高級編程語言想要成為可執(zhí)行文件需要先編譯為匯編語言再匯編為機器語言显歧,機器語言也是計算機能夠識別的唯一語言,但是OC并不能直接編譯為匯編語言确镊,而是要先轉(zhuǎn)寫為純C語言再進行編譯和匯編的操作士骤,從OC到C語言的過渡就是由runtime來實現(xiàn)的。然而我們使用OC進行面向?qū)ο箝_發(fā)蕾域,而C語言更多的是面向過程開發(fā)拷肌,這就需要將面向?qū)ο蟮念愞D(zhuǎn)變?yōu)槊嫦蜻^程的結(jié)構(gòu)體。

RunTime的使用場景束铭?

場景1-交換方法

在真正做項目的時候廓块,有時候會接受不同的項目,但是對于你接受的項目契沫,有自己新搭建的項目带猴,也有經(jīng)過很多人手的項目,參差不齊懈万,對于有些需求拴清,修改涉及到以前的代碼,如果一點點的修改会通,費時費力而且見效很慢口予,這時候就可以使用Runtime的交換方法來統(tǒng)一處理,我在做項目的時候就遇到過這種需求涕侈,需要將項目中所有有負值的地方全部處理成紅色沪停,我采用的就是和系統(tǒng)的setText:方法交換,僅僅就換了幾分鐘就將這個需求搞定裳涛。

#import <UIKit/UIKit.h>?

@interface UILabel (TextStyle)?

@end

#import "UILabel+TextStyle.h"

#import?<objc/runtime.h>

@implementation UILabel (TextStyle) ?

+ (void) load { ? ?

????Method method1 = class_getInstanceMethod([UILabel class], @selector(setText:)); ? ? ????Method method2 = class_getInstanceMethod([UILabel class],@selector(setTextString:)); ? ?

????method_exchangeImplementations(method1, method2);

} ?

- (void)setTextString:(NSString *)textString { ? ?

????if (![textString isEqualToString:@"-"] && [textString hasPrefix:@"-"]) {

????//對于負值進行標紅處理 ? ? ? ?

????????self.textColor = [UIColor redColor]; ? ?

????} ? ?

????[self setTextString:textString];

}

@end

這里我就將setText:setTextString:交換木张,之前使用label給text賦值的語句,其實全部調(diào)用的

setTextString:方法給label賦值端三,這樣就完成了對項目的修改舷礼。

場景2-動態(tài)擴展屬性

OC中類可以通過Category來直接擴展方法,但是卻不能直接通過添加屬性來擴展屬性(以我項目中用到的一個為例)郊闯。

這里需要使用到objc_setAssociatedObject()objc_getAssociatedObject()方法妻献;

OBJC_EXPORT void objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy)

objc_setAssociatedObject()的主要作用是:讓一個對象和另一個對象關(guān)聯(lián)起來蛛株,即一個對象保持對另一個對象的引用,并可以獲取這個對象育拨。關(guān)鍵字是一個void類型的指針谨履。每個關(guān)鍵字必須是唯一的,通常都是會采用靜態(tài)變量來作為關(guān)鍵字至朗。

OBJC_EXPORT id objc_getAssociatedObject(id object, const void *key) OBJC_AVAILABLE(10.6, 3.1, 9.0, 1.0);

#import <UIKit/UIKit.h>

?@interface UIView (SPUtils)?

????@property(nonatomic) NSString * testString;?

@end

#import "UIView+SPUtils.h"

#import <objc/runtime.h>

@implementation UIView (SPUtils)

-(void)setTestString:(NSString?*)testString{

????objc_setAssociatedObject(self, @selector(testString), testString,OBJC_ASSOCIATION_RETAIN);

}

-(NSString?*)testString{????

????return?objc_getAssociatedObject(self,?_cmd);

}

?@end

這樣在使用在其他中創(chuàng)建UIView對象屉符,可以直接使用testString屬性了!


場景3-實現(xiàn)字典和模型的自動轉(zhuǎn)換(MJExtension)

使用RunTime提供的函數(shù)遍歷model自身的所有屬性锹引,如果屬性在json中有對應的值矗钟,則將其復制。核心方法:在NSObject的分類中添加方法嫌变。

#import <Foundation/Foundation.h>

?@interface?NSObject?(MutableCopy)?

- (instancetype) initWithDict:(NSDictionary *)dict;?

@end

#import "NSObject+MutableCopy.h"

#import <objc/runtime.h>?

@implementation?NSObject?(MutableCopy)

- (instancetype) initWithDict:(NSDictionary *)dict{

????if (self = [self init]) {

????????//(1)獲取類的屬性及屬性對應的類型

????????NSMutableArray * keys = [NSMutableArray array];????????

????????NSMutableArray?*?attributes?=?[NSMutableArray?array];

????????unsigned int outCount;

????????objc_property_t * properties = class_copyPropertyList([self class], &outCount);

? ? ? ? for (int i = 0; i < outCount; i ++) {

????????????objc_property_t property = properties[i];

????????????//通過property_getName函數(shù)獲得屬性的名字

????????????NSString * propertyName = [NSString stringWithCString:property_getName(property) encoding:NSUTF8StringEncoding];

????????????[keys addObject:propertyName];

????????????//通過property_getAttributes函數(shù)可以獲得屬性的名字和@encode編碼

????????????NSString * propertyAttribute = [NSString stringWithCString:property_getAttributes(property) encoding:NSUTF8StringEncoding];????

????????????[attributes addObject:propertyAttribute];

????????} //立即釋放properties指向的內(nèi)存

????????free(properties);

????????//(2)根據(jù)類型給屬性賦值

????????for (NSString * key in keys) {

????????????if ([dict valueForKey:key] == nil) continue;

????????????[self setValue:[dict valueForKey:key] forKey:key];

????????}

????}

return self;

}?

@end

目前就RunTime就研究這么多吨艇,有興趣的點個關(guān)注,關(guān)注不迷路額L谏丁6小!喜歡的朋友可以關(guān)注個人微信公眾號:IT科學技術(shù)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末倘待,一起剝皮案震驚了整個濱河市疮跑,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌凸舵,老刑警劉巖祖娘,帶你破解...
    沈念sama閱讀 221,888評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異啊奄,居然都是意外死亡渐苏,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,677評論 3 399
  • 文/潘曉璐 我一進店門菇夸,熙熙樓的掌柜王于貴愁眉苦臉地迎上來琼富,“玉大人,你說我怎么就攤上這事庄新【厦迹” “怎么了?”我有些...
    開封第一講書人閱讀 168,386評論 0 360
  • 文/不壞的土叔 我叫張陵择诈,是天一觀的道長凡蚜。 經(jīng)常有香客問我,道長吭从,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,726評論 1 297
  • 正文 為了忘掉前任恶迈,我火速辦了婚禮涩金,結(jié)果婚禮上谱醇,老公的妹妹穿的比我還像新娘。我一直安慰自己步做,他們只是感情好副渴,可當我...
    茶點故事閱讀 68,729評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著全度,像睡著了一般煮剧。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上将鸵,一...
    開封第一講書人閱讀 52,337評論 1 310
  • 那天勉盅,我揣著相機與錄音,去河邊找鬼顶掉。 笑死草娜,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的痒筒。 我是一名探鬼主播宰闰,決...
    沈念sama閱讀 40,902評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼簿透!你這毒婦竟也來了移袍?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,807評論 0 276
  • 序言:老撾萬榮一對情侶失蹤老充,失蹤者是張志新(化名)和其女友劉穎葡盗,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蚂维,經(jīng)...
    沈念sama閱讀 46,349評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡戳粒,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,439評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了虫啥。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蔚约。...
    茶點故事閱讀 40,567評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖涂籽,靈堂內(nèi)的尸體忽然破棺而出苹祟,到底是詐尸還是另有隱情,我是刑警寧澤评雌,帶...
    沈念sama閱讀 36,242評論 5 350
  • 正文 年R本政府宣布树枫,位于F島的核電站,受9級特大地震影響景东,放射性物質(zhì)發(fā)生泄漏砂轻。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,933評論 3 334
  • 文/蒙蒙 一斤吐、第九天 我趴在偏房一處隱蔽的房頂上張望搔涝。 院中可真熱鬧厨喂,春花似錦、人聲如沸庄呈。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,420評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽诬留。三九已至斜纪,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間文兑,已是汗流浹背盒刚。 一陣腳步聲響...
    開封第一講書人閱讀 33,531評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留彩届,地道東北人伪冰。 一個月前我還...
    沈念sama閱讀 48,995評論 3 377
  • 正文 我出身青樓,卻偏偏與公主長得像樟蠕,于是被迫代替她去往敵國和親贮聂。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,585評論 2 359

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