亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

runtime 理解

2019-11-08 00:20:31
字體:
來源:轉載
供稿:網友

大家知道OC是一門動態語言,他將一些靜態語言以及庫的鏈接的一些事情放在運行時來進行處理,這就給我們增加了編程的靈活性,比如可以隨意交換兩個方法的執行,消息的轉發等等。這就是Runtime運行時。這個庫全部由C語言來編寫的,該對象用結構體來表示,方法使用C函數來表示。當這些結構體以及方法用runtime函數來修飾封裝后,我們就可以對類和對象進行創建、檢查、修改等操作了。

1、基本結構

/// An opaque type that rePResents a method in a class definition.類中定義的方法

typedefstruct objc_method *Method;

/// An opaque type that represents an instance variable.類中定義的實例變量

typedefstruct objc_ivar *Ivar;

/// An opaque type that represents a category.類別

typedefstruct objc_category *Category;

/// An opaque type that represents an Objective-C declared property.類中聲明的屬性

typedefstruct objc_property *objc_property_t;

struct objc_class {

    Class isa  OBJC_ISA_AVAILABILITY; isa指針,通過它可以找到對象所述的類,isa指針在代碼運行時并不總是指向實例所屬的類,因此不能通過其獲取類型,但是可以通過‘’-class來確定。KVO的實現機理就是通過isa指針指向一個中間類而不是真實類來實現的。

#if !__OBJC2__

    Class super_class                                        OBJC2_UNAVAILABLE;

    constchar *name                                         OBJC2_UNAVAILABLE;   ------類名

    long version                                             OBJC2_UNAVAILABLE;

    long info                                                OBJC2_UNAVAILABLE;

    long instance_size                                       OBJC2_UNAVAILABLE;

    struct objc_ivar_list *ivars                             OBJC2_UNAVAILABLE;  ------屬性列表

    struct objc_method_list **methodLists                    OBJC2_UNAVAILABLE;------方法列表

    struct objc_cache *cache                                 OBJC2_UNAVAILABLE;------緩存,一種優化機制

    struct objc_protocol_list *protocols                     OBJC2_UNAVAILABLE;------協議列表

#endif

} OBJC2_UNAVAILABLE;

/* Use `Class` instead of `struct objc_class *` */

2、常用的獲取列表的屬性

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]); NSLog(@"property---->%@", [NSString stringWithUTF8String:propertyName]); } //獲取方法列表 Method *methodList = class_copyMethodList([self class], &count); for (unsigned int i; i<count; i++) { Method method = methodList[i]; NSLog(@"method---->%@", NSStringFromSelector(method_getName(method))); } //獲取成員變量列表 Ivar *ivarList = class_copyIvarList([self class], &count); for (unsigned int i; i<count; i++) { Ivar myIvar = ivarList[i]; const char *ivarName = ivar_getName(myIvar); NSLog(@"Ivar---->%@", [NSString stringWithUTF8String:ivarName]); } //獲取協議列表 __unsafe_unretained Protocol **protocolList = class_copyProtocolList([self class], &count); for (unsigned int i; i<count; i++) { Protocol *myProtocal = protocolList[i]; const char *protocolName = protocol_getName(myProtocal); NSLog(@"protocol---->%@", [NSString stringWithUTF8String:protocolName]); }3、消息轉發

在OC中調用方法一般是如下調用

id returnValue = [someObject messageName:parameter];,someObject是消息的接受者,messageName是一個選擇器,parameter則為參數。選擇器+參數 就是我們所稱為的消息。

其在底層中是將我們的消息轉換為標準的C語言函數,Void objc_msgSend(id self , SEL cmd , .....)  ,self 為消息接收者,cmd為選擇器,省略號為參數,表示可變長度參數。因此以上的消息方法會轉換為id returnValue = objc_msgSend( someObject , @selector(messageName:) , parameter);

之所以Objc_msgsend方法總能找到正確的函數去執行,原因是OC中每個類都有一張方法的列表存儲這個類的所有方法,當發出objc_msgsend時,會根據object的isa指針找到類結構的方法,如果找不到則會到父類尋找該方法的實現,直到NSObject類。上面有提到cach緩存機制,蘋果為了加快尋找速率,runtime 系統會緩存使用過的SEL 和方法地址。

通過object的isa指針找到他的類結構class在在相應操作的對象中的緩存方法列表中找調用的方法,如果找到,轉向相應實現并執行(IMP)如果沒找到,在相應操作的對象中的方法列表中找調用的方法,如果找到,轉向相應實現執行(IMP)如果還未找到則會去父類中重復上面操作尋找如果最終還是未找到,則會調用實例方法調用+(bool)resolveInstanceMethod:(SEL)sel ;類方法調用:+(bool)resolveClassMethod:(SEL)sel;如果返回為YES,則會重啟一次消息發送過程,調用你自己添加的方法。

+ (BOOL)resolveInstanceMethod:(SEL)sel

{

    if (sel ==@selector(sendMessage:)) {

        class_addMethod([selfclass], sel,imp_implementationWithBlock(^(idself,NSString *Word) {

            NSLog(@"method resolution way : send message = %@", word);

        }), "v@*");

    }

    returnYES;

}

- (void)sendMessage:(NSString *)word

{

    NSLog(@"normal way : send message = %@", word);

}

如果返回NO,則會調用- (id)forwardingTargetForSelector:(SEL)aSelector方法,再次方法中可以將你調用的不存在的方法重定向到一個其他聲明了這個方法的類,只需要你返回一個有這個方法的target,

- (id)forwardingTargetForSelector:(SEL)aSelector

{

    if (aSelector ==@selector(sendMessage:)) {

        return [MessageForwardingnew];//新建的類,見下

    }

    returnnil;

}

#import <Foundation/Foundation.h>

@interface MessageForwarding :NSObject

- (void)sendMessage:(NSString *)word;

@end

如果return nil,則會- (void)forwardInvocation:(NSInvocation *)anInvocation將你調用的不存在的方法打包成NSInvocation傳給你。做完你自己的處理后,調用invokeWithTarget:方法讓某個target觸發這個方法。

- (void)forwardInvocation:(NSInvocation *)anInvocation

{

    MessageForwarding *messageForwarding = [MessageForwardingnew];

    if ([messageForwardingrespondsToSelector:anInvocation.selector]) {

        [anInvocationinvokeWithTarget:messageForwarding];

    }

}

#import <Foundation/Foundation.h>

@interface MessageForwarding :NSObject

- (void)sendMessage:(NSString *)word;

@end

4、runtime實際應用

更改私有屬性 、給category添加屬性、歸檔解檔、AOP等等,具體事例請看本博客其他文章


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
最近中文字幕2019免费| 中文字幕亚洲一区在线观看| 97碰碰碰免费色视频| 欧美壮男野外gaytube| 亚洲欧美国产一本综合首页| 国产精品久久久久久久天堂| 精品视频在线播放| 欧美性xxxx在线播放| 欧美一级大胆视频| 91精品国产777在线观看| 国产日韩欧美夫妻视频在线观看| 国产不卡在线观看| 国产精品一区久久久| 欧美一级片一区| 久久99亚洲热视| 一区二区三区精品99久久| 日韩免费av片在线观看| 欧美日韩亚洲91| 亚洲午夜性刺激影院| 成人av在线天堂| 亚洲欧美一区二区激情| 亚洲精品久久久久久下一站| 亚洲午夜小视频| 精品日本高清在线播放| 亚洲国产精久久久久久| 欧美最猛性xxxxx亚洲精品| 日韩欧美亚洲综合| 在线精品视频视频中文字幕| 国产精品999| 久久精品国产69国产精品亚洲| 国产精品稀缺呦系列在线| 91沈先生作品| 久久精品中文字幕电影| 日本午夜人人精品| www欧美xxxx| 97精品一区二区视频在线观看| 国产精品自在线| 人人做人人澡人人爽欧美| 亚洲va欧美va在线观看| 国产噜噜噜噜噜久久久久久久久| 91香蕉嫩草影院入口| 欧美成人免费小视频| 日韩综合视频在线观看| 国产亚洲精品久久久久久牛牛| 亚洲电影免费观看高清完整版在线| 日韩激情视频在线播放| 欧美日本亚洲视频| 91精品国产高清久久久久久| 亚洲福利精品在线| 日韩大胆人体377p| 在线观看免费高清视频97| 欧美日韩国产丝袜另类| 日韩av毛片网| 成人97在线观看视频| 亚洲男人天堂2024| 77777少妇光屁股久久一区| 国产精品美女久久久免费| 国产欧美一区二区三区在线看| 伊人伊成久久人综合网站| 亚洲精品理论电影| 日韩欧美在线视频日韩欧美在线视频| 色婷婷亚洲mv天堂mv在影片| 91精品国产高清久久久久久久久| 色婷婷综合久久久久| 亚洲男人天堂网| 日韩精品日韩在线观看| 色偷偷偷综合中文字幕;dd| 日韩中文字幕精品| 日韩av免费网站| 久久手机精品视频| 成人av.网址在线网站| 久久九九全国免费精品观看| 久久av.com| 97人洗澡人人免费公开视频碰碰碰| 精品色蜜蜜精品视频在线观看| 久热在线中文字幕色999舞| 日韩在线观看免费全集电视剧网站| 黄色一区二区在线| 在线视频欧美性高潮| 欧美精品久久久久久久免费观看| 欧美又大又粗又长| 精品欧美国产一区二区三区| 国产精品揄拍一区二区| 26uuu亚洲国产精品| 欧美日韩国产一区二区| 91日本在线视频| 欧美亚洲视频在线观看| 97成人精品视频在线观看| 国产精品久久久久久久久久久新郎| 久久久综合av| 亚洲视频在线观看| 欧美电影免费观看| 91av在线免费观看视频| 亚洲国产精品视频在线观看| 久久久久国产精品一区| 欧美风情在线观看| 日韩人体视频一二区| 色哟哟网站入口亚洲精品| 欧美日韩国产页| 亚洲美女精品成人在线视频| 久久五月情影视| 欧美一级免费看| 性色av香蕉一区二区| 日韩一区av在线| 久久999免费视频| 国产成人精品一区二区在线| 亚洲美腿欧美激情另类| 精品国产电影一区| 成人在线一区二区| 日韩精品在线观看网站| 亚洲系列中文字幕| 欧美多人爱爱视频网站| 国产精品视频公开费视频| 在线视频精品一| 欧美精品一区二区免费| 欧美性xxxxxxx| 久久久久久久久久国产| 国产精品视频免费在线观看| 欧美一级淫片aaaaaaa视频| 日日骚久久av| 欧美日韩成人网| 粗暴蹂躏中文一区二区三区| 欧美日韩第一视频| 久久精品男人天堂| 亚洲第一av在线| 最近中文字幕mv在线一区二区三区四区| 欧美性猛交xxxx免费看| 欧美孕妇与黑人孕交| 亚洲欧美另类人妖| 中文字幕久精品免费视频| 色樱桃影院亚洲精品影院| 国产精品99蜜臀久久不卡二区| 欧美成人午夜激情视频| 欧美一区二区三区免费视| 国产精品久久久久久亚洲影视| 欧美丰满片xxx777| 深夜福利亚洲导航| 成人免费高清完整版在线观看| 国产欧美日韩精品丝袜高跟鞋| 亚洲天堂日韩电影| 国产日韩亚洲欧美| 亚洲日本欧美中文幕| 国产亚洲精品久久久久久牛牛| 亚洲美女久久久| 欧洲中文字幕国产精品| 欧美成人精品在线播放| 久久久久成人精品| 日韩激情av在线免费观看| 国产精品久久久久久久午夜| www.日韩欧美| 亚洲福利视频在线| 日韩欧美大尺度| 9.1国产丝袜在线观看| 亚洲一区二区三区视频| 精品伊人久久97| 欧美国产日本高清在线| 欧美做受高潮电影o| 欧美日韩视频在线| 91爱爱小视频k| 久久精品成人动漫| 亚洲一区二区三区久久| 欧美一区二区影院| 国产成人拍精品视频午夜网站| 欧美老女人bb|