你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發綜合 >> 了解OC的Runtime

了解OC的Runtime

編輯:IOS開發綜合

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】的相關資料介紹到這裡,希望對您有所幫助! 提示:不會對讀者因本文所帶來的任何損失負責。如果您支持就請把本站添加至收藏夾哦!

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved