OC的Runtime是指運轉時,望文生義在編譯進程中並不能真正決議要調用哪個辦法,要等運轉的時分,才依據辦法的稱號找到相應的辦法來執行。
音訊發送機制當調用一個對象的辦法時,實踐上是在給對象發送音訊,OC代碼會被轉化成Runtime的C代碼執行,[obj target]會被轉化成:objc_msgSend(obj,@selector(target));
然後這個函數經過對象的isa找到相應的Class。先在Class 的cache中對應的辦法,假如未找到,再去methodList中查找,若methodList中未找到,則去superClass中的methodList中查找。
最後,若能找到,則將辦法參加cache中,以便下次查找(這樣能進步功能),然後執行這個辦法。
若找不到,轉向‘阻攔調用辦法’,假如‘阻攔調用辦法’沒有重寫,拋出異常。
阻攔調用辦法在找不到辦法、順序解體之前,你還無機會重寫NSObject的四個辦法來處置
// 處置類辦法
+ (BOOL)resolveClassMethod:(SEL)sel;
// 處置實例辦法
+ (BOOL)resolveInstanceMethod:(SEL)sel;
// 重定向到另一個完成了該辦法的對象中,只需求前往這個對象即可
- (id)forwardingTargetForSelector:(SEL)aSelector;
// 把那個不存在的辦法打包成NSInvocation傳給你。做完你自己的處置後,調用invokeWithtarget:辦法讓某個target觸發這個辦法。
- (void)forwardInvocation:(NSInvocation *)anInvocation;
+resolveInstanceMethod:或許 +resolveClassMethod:,讓你無機會提供一個函數完成。假如你添加了函數並前往 YES,那運轉時零碎就會重新啟動一次音訊發送的進程,假如 resolve 辦法前往 NO ,運轉時就會移到下一步:音訊轉發
假如目的對象完成了-forwardingTargetForSelector:,Runtime 這時就會調用這個辦法,給你把這個音訊轉發給其他對象的時機。 只需這個辦法前往的不是nil和self,整個音訊發送的進程就會被重啟,當然發送的對象會變成你前往的那個對象。否則,就會持續Normal Fowarding。 這裡叫Fast,只是為了區別下一步的轉發機制。由於這一步不會創立任何新的對象,但下一步-forwardInvocation:會創立一個NSInvocation對象,所以絕對更快點
Normal forwarding,這一步是Runtime最後一次給你援救的時機。首先它會發送-methodSignatureForSelector:音訊取得函數的參數和前往值類型,假如前往nil,Runtime則會收回-doesNotRecognizeSelector:音訊,順序這時也就掛掉了。假如前往了一個函數簽名,Runtime就會創立一個NSInvocation對象並發送-forwardInvocation:音訊給目的對象。
關聯對象假如只想給一個類添加一個屬性,那麼重新寫一個類並承繼它顯得很費事,這時Runtime的‘關聯對象函數’就發揚作用了。
在運用‘關聯對象函數’之前,要引入Runtime的庫
#import <objc/runtime.h>
將‘關聯對象函數’封裝為辦法,放在你的categroy中
//添加關聯對象
- (void)addAssociatedObject:(id)object {
objc_setAssociatedObject(self, @selector(getAssociatedObject), object, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
//獲取關聯對象
- (id)getAssociatedObject {
return objc_getAssociatedObject(self, _cmd);
}
獲取列表
有時分需求知道對象中的屬性名和函數名,可以用Runtime的‘獲取列表函數’
異樣將這幾個函數封裝成辦法,放在你的category中
- (NSArray*)dptPropertyList {
NSMutableArray *resultList = [[NSMutableArray alloc] initWithCapacity:3];
unsigned int count;
objc_property_t *propertyList = class_copyPropertyList([self class], &count);
for (unsigned int i=0; i<count; i++) {
const char *propertyName = property_getName(propertyList[i]);
[resultList addObject:[NSString stringWithUTF8String:propertyName]];
}
return resultList;
}
- (NSArray*)dptMethodList {
NSMutableArray *resultList = [[NSMutableArray alloc] initWithCapacity:3];
unsigned int count;
Method *methodList = class_copyMethodList([self class], &count);
for (unsigned int i=0; i<count; i++) {
Method method = methodList[i];
SEL methodSEL = method_getName(method);
const char *methodName = sel_getName(methodSEL);
[resultList addObject:[NSString stringWithUTF8String:methodName]];
}
return resultList;
}
參考文章
IOS:學習Runtime的了解和心得
Objective-C總Runtime的那點事兒(一)音訊機制
【了解OC的Runtime】的相關資料介紹到這裡,希望對您有所幫助! 提示:不會對讀者因本文所帶來的任何損失負責。如果您支持就請把本站添加至收藏夾哦!