iOS Runtime

隨便說(shuō)說(shuō)在新人眼中很復(fù)雜的runtime.....

運(yùn)行時(shí)機(jī)制是什么呢?官方這么說(shuō)TheObjective-Clanguage defers as many decisions as it can from compile time and link time to runtime. Whenever possible, it does things dynamically. This means that the language requires not just a compiler, but also a runtime system to execute the compiled code. The runtime system acts as a kind of operating system for theobjective-clanguage; it’s what makes the language work.

大家是這么理解的。所謂運(yùn)行時(shí), 就是盡可能地把決定從編譯器推遲到運(yùn)行期, 就是盡可能地做到動(dòng)態(tài). 只是在運(yùn)行的時(shí)候才會(huì)去確定對(duì)象的類型和方法的. 因此利用Runtime機(jī)制可以在程序運(yùn)行時(shí)動(dòng)態(tài)地修改類和對(duì)象中的所有屬性和方法.Objective-C中調(diào)用對(duì)象的方法時(shí), 會(huì)向該對(duì)象發(fā)送一條消息, runtime根據(jù)該消息做出反應(yīng).也有這么理解的Objective-C語(yǔ)言是一門動(dòng)態(tài)語(yǔ)言,它將很多靜態(tài)語(yǔ)言在編譯和鏈接時(shí)期做的事放到了運(yùn)行時(shí)來(lái)處理。對(duì)于Objective-C來(lái)說(shuō),這個(gè)運(yùn)行時(shí)系統(tǒng)就像一個(gè)操作系統(tǒng)一樣:它讓所有的工作可以正常的運(yùn)行。Runtime基本上是用C和匯編寫(xiě)的,這個(gè)庫(kù)使得C語(yǔ)言有了面向?qū)ο蟮哪芰Α?/p>

簡(jiǎn)單的來(lái)說(shuō)就是蘋(píng)果官方的一套C語(yǔ)言庫(kù),然后能做一些底層的操作。到底學(xué)習(xí)runTime要學(xué)習(xí)哪些方法哪些類呢。。官方其實(shí)說(shuō)的很清楚,附上鏈接https://developer.apple.com/documentation/objectivec/objective_c_runtime

下面我就說(shuō)一些平常工作中比較實(shí)用的,也很基礎(chǔ)的runtime用法

① ?交換兩個(gè)方法的實(shí)現(xiàn)

首先創(chuàng)建一個(gè)Person類,有以下方法和屬性

/**名稱 */

@property(nonatomic,copy)NSString *name;

/**年齡 */

@property(nonatomic,assign)NSInteger age;

-(void)run;

-(void)eat;

然后實(shí)現(xiàn)下面的方法

Method runMethod = class_getInstanceMethod([Person class], @selector(run));

Method eatMethod = class_getInstanceMethod([Person class], @selector(eat));

method_exchangeImplementations(runMethod, eatMethod);

Person *p = [[Person alloc]init];

[p run];

[p eat];

通過(guò)運(yùn)行我們發(fā)現(xiàn)[p run] 其實(shí)是調(diào)用的[p eat]方法

②,獲取一個(gè)類的所有屬性

unsigned int count = 0;

objc_property_t *porpertys = class_copyPropertyList([Person class], &count);

for (int i = 0; i < count; i++) {

const char *name = property_getName(porpertys[i]);

NSString *perporyName = [NSString stringWithCString:name encoding:NSUTF8StringEncoding];

NSLog(@"%@",perporyName);

}

free(porpertys);//一定別忘記釋放,不然會(huì)有內(nèi)存泄漏

③,取出一個(gè)類的成員變量(私有的也能得到)

unsigned int count2 = 0;

Ivar *ivarlist = class_copyIvarList([Person class], &count2);

for (int i = 0; i < count2; i++) {

Ivar ivar = *(ivarlist + i);

const char *name = ivar_getName(ivar);

NSString *ivarName = [NSString stringWithCString:name encoding:NSUTF8StringEncoding];

NSLog(@"ivarName ----%@",ivarName);

}

free(ivarlist);

④ 獲取一個(gè)類的所有方法

unsigned int methodCount = 0;

Method *methods = class_copyMethodList([Person class], &methodCount);

for (int i = 0; i < methodCount; i++){

SEL methodName = method_getName(methods[i]);

NSString *name = [NSString stringWithCString:sel_getName(methodName) encoding:NSUTF8StringEncoding];

NSLog(@"%@",name);

}

free(methods);

⑤,動(dòng)態(tài)的添加一些屬性

1.設(shè)置關(guān)聯(lián)值

參數(shù)說(shuō)明:

object:與誰(shuí)關(guān)聯(lián),通常是傳self

key:唯一鍵,在獲取值時(shí)通過(guò)該鍵獲取,通常是使用static

const void *來(lái)聲明

value:關(guān)聯(lián)所設(shè)置的值

policy:內(nèi)存管理策略,比如使用copy

void objc_setAssociatedObject(id object, const void *key, id value, objc _AssociationPolicy policy)

2.獲取關(guān)聯(lián)值

參數(shù)說(shuō)明:

object:與誰(shuí)關(guān)聯(lián),通常是傳self,在設(shè)置關(guān)聯(lián)時(shí)所指定的與哪個(gè)對(duì)象關(guān)聯(lián)的那個(gè)對(duì)象

key:唯一鍵,在設(shè)置關(guān)聯(lián)時(shí)所指定的鍵

id objc_getAssociatedObject(id object, const void *key)

3.取消關(guān)聯(lián)

void objc_removeAssociatedObjects(id object)

最后編輯于
?著作權(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)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

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