隨便說(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)