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

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

objc語言的運行時處理

2019-11-14 20:42:57
字體:
來源:轉載
供稿:網友

在Objective-C中,消息是通過objc_msgSend()這個runtime方法及相近的方法來實現的。這個方法需要一個target,selector,還有一些參數。理論上來說,編譯器只是把消息分發變成objc_msgSend來執行。比如下面這兩行代碼是等價的。

1 [array insertObject:foo atIndex:5];  2 objc_msgSend(array, @selector(insertObject:atIndex:), foo, 5);

class的方法列表其實是一個字典,key為selectors,IMPs為value。一個IMP是指向方法在內存中的實現。很重要的一點是,selector和IMP之間的關系是在運行時才決定的,而不是編譯時。這樣我們就能玩出些花樣。

IMP通常是指向方法的指針,第一個參數是self,類型為id,第二個參數是_cmd,類型為SEL,余下的是方法的參數。這也是self_cmd被定義的地方。下面演示了Method和IMP

1 - (id)doSomethingWithInt:(int)aInt{} 2 id doSomethingWithInt(id self, SEL _cmd, int aInt){}

 

objc中存在一些用于修改和自省的方法,這些方法差不多都是以特定的前綴開頭,如

class_addIvar, class_addMethod,class_addPRoperty和class_addProtocol

允許重建classes,

class_copyIvarList,class_copyMethodList, class_copyProtocolList和class_copyPropertyList

能拿到一個class的所有內容,而

class_getClassMethod, class_getClassVariable, class_getInstanceMethod,class_getInstanceVariable, class_getMethodImplementation和class_getProperty

返回單個內容。也有些用于自省的方法,如

class_conformsToProtocol, class_respondsToSelector,class_getSuperclass。

最后,你可以使用class_createInstance來創建一個object。

比較基礎的一個動態特性是通過String來生成Classes和Selectors。Cocoa提供了NSClassFromStringNSSelectorFromString方法,使用起來很簡單

1 Class stringclass = NSClassFromString(@"NSString");2 NSString *myString = [stringclass stringWithString:@"Hello World"];

為什么要這么做呢,直接使用class不是更方便,通常情況下,但有些場景有會很能有用,首先可以得知某個class是否存在,因為不存在的話NSClassFromString會返回nil,用于檢查。另一個常見的場景是根據不同的輸入返回不同的class跟method。在解析數據的時候,下面是一個例子

- (void)parSEObject:(id)object {    for (id data in object) {        if ([[data type] isEqualToString:@"String"]) {            [self parseString:[data value]];         } else if ([[data type] isEqualToString:@"Number"]) {            [self parseNumber:[data value]];        } else if ([[data type] isEqualToString:@"Array"]) {            [self parseArray:[data value]];        }    }}- (void)parseObjectDynamic:(id)object {    for (id data in object) {        [self performSelector:NSSelectorFromString([NSString stringWithFormat:@"parse%@:", [data type]]) withObject:[data value]];    }}- (void)parseString:(NSString *)aString {}- (void)parseNumber:(NSString *)aNumber {}- (void)parseArray:(NSString *)aArray {}

可以看到用了后者的話可以把代碼行數降下來,將來如果有新的類型,只需要增加實現方法即可,而不用去添加新的else if.

在objc中,方法由兩部分組成,selector相當于一個方法的id,IMP是方法的實現,這樣分開的一個便利之處就是selector和IMP之間的對應關系可以被改變。這就是Method Swizzling的存在處,交換兩個方法的實現,下面是代碼實現:

 1 void MethodSwizzle(Class aClass, SEL orig_sel, SEL alt_sel){ 2     Method orig_method = nil, alt_method = nil; 3     // First, look for the methods 4     orig_method = class_getInstanceMethod(aClass, orig_sel); 5     alt_method = class_getInstanceMethod(aClass, alt_sel); 6     // If both are found, swizzle them 7     if ((orig_method != nil) && (alt_method != nil)){ 8         char *temp1; 9         IMP temp2;10         temp1 = orig_method->method_types;11         orig_method->method_types = alt_method->method_types;12         alt_method->method_types = temp1;13         temp2 = orig_method->method_imp;14         orig_method->method_imp = alt_method->method_imp;15         alt_method->method_imp = temp2;16     }
17 }

當然,上面的第八行開始到十五行之間的代碼可以用如下進行替換。

method_exchangeImplementations(orig_method,alt_method)

上面我們談到了方法交換,但是當你發送了一個object無法處理的消息時會發生什么呢?這里首先會是動態方法處理

1 resolveInstanceMethod && resolveClassMethod

在這兩個重寫的地方運用class_addMethod,同時記得返回YES,下面是一個例子

1 + (BOOL)resolveInstanceMethod:(SEL)aSelector {2     if (aSelector == @selector(myDynamicMethod)) {3         class_addMethod(self, aSelector, (IMP)myDynamicIMP, "v@:");4         return YES;5     }6     return [super resolveInstanceMethod:aSelector];7 }

如果resolve method返回了NO,那么運行時就進入下一個步驟--消息轉發。首先會調用-forwardingTargetForSelector:,如果只是把消息發送到另一個object,那么就用這個方法,但是如果你想修改消息,那么就要使用-forwardInvocation:,將消息打包成NSInvocation,調用invokeWithTarget:

整個文章下來,可以看到objc表面看起來跟c#,java等語言在方法調用上沒什么區別,但最關鍵的是objc的運行時消息處理,我們可以在消息處理上添加更多的自由,其優勢在于在不擴展語言本身的情況下做很多事,比如KVO,提供了優雅的API來與已有的代碼進行無疑結合。

下面就結合運行時來談談KVO的內部真正實現。當你第一次觀察某個object時,runtime會創建一個新的繼承原先class的subclass。在這個新的class中,它重寫了所有被觀察的key,然后將object的isa指針指向新創建的class(這個指針告訴Objective-C運行時某個object到底是哪種類型的object)。所以object神奇地變成了新的子類的實例。

 

 


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
中文字幕久久精品| 国产精品成人国产乱一区| 在线电影中文日韩| 久久久久久网址| 欧美国产第二页| www.xxxx精品| 欧美丰满老妇厨房牲生活| 日韩成人xxxx| 亚洲天堂一区二区三区| 欧美裸体xxxxx| 国产伊人精品在线| 亚洲一区二区三区sesese| 欧美日韩免费一区| 亚洲在线观看视频网站| 亚洲欧美日韩一区在线| 久久久久久久久中文字幕| 久久久久久久999精品视频| 久久免费视频在线观看| 2020国产精品视频| 国产精品69精品一区二区三区| 亚洲美女激情视频| 日韩中文理论片| 国产91ⅴ在线精品免费观看| 欧美一区二粉嫩精品国产一线天| 夜色77av精品影院| 91精品久久久久久久久中文字幕| 在线日韩中文字幕| 日韩欧美在线视频免费观看| 91av在线免费观看| 日韩精品亚洲视频| 日韩电影中文字幕在线| 中文字幕在线看视频国产欧美| 在线视频一区二区| 亚洲欧洲黄色网| 亚洲第一区在线| 国产精品高潮呻吟久久av无限| 国产成人精品一区二区| 国产91成人在在线播放| 成人福利网站在线观看11| 精品日韩视频在线观看| 丰满岳妇乱一区二区三区| 亚洲天堂第二页| 136fldh精品导航福利| 5566日本婷婷色中文字幕97| 欧美日韩色婷婷| 日韩av手机在线观看| 亚洲性xxxx| 亚洲国内精品视频| 中文字幕亚洲欧美日韩在线不卡| 亚洲人成电影在线观看天堂色| 国产成人精品免费视频| 一区国产精品视频| 久久亚洲精品一区| 亚洲韩国日本中文字幕| 亚洲综合在线中文字幕| 久久久伊人日本| 精品欧美aⅴ在线网站| 欧美激情一区二区三区高清视频| 91干在线观看| 91精品一区二区| 国模视频一区二区| 亚洲影院污污.| 亚洲男人天堂2019| 亚洲自拍另类欧美丝袜| 亚洲欧美在线看| 国产精品美女www爽爽爽视频| 久久精品99久久久久久久久| 国产精品露脸av在线| 色综合天天综合网国产成人网| 最近2019年手机中文字幕| 91精品国产综合久久久久久蜜臀| 最新国产成人av网站网址麻豆| 欧美日韩免费在线观看| 国产女同一区二区| 性色av一区二区三区在线观看| 欧洲成人性视频| 国产美女高潮久久白浆| 亚洲欧美日韩视频一区| 国产91精品高潮白浆喷水| 久久久视频在线| 久久免费视频在线| 精品高清一区二区三区| 亚洲黄页网在线观看| 欧美在线视频观看| 欧美亚洲第一区| 亚洲www在线| 国产精品白丝av嫩草影院| 亚洲欧洲午夜一线一品| 国产精品久久中文| 欧美精品精品精品精品免费| 国产欧美精品日韩| 久久久久国色av免费观看性色| 亚洲欧美日韩精品| 日韩精品视频中文在线观看| 亚洲精品久久久久中文字幕二区| 久久亚洲欧美日韩精品专区| 欧美老女人www| 亚洲欧美另类中文字幕| 日韩欧美在线一区| 成人黄色av网站| 欧美激情二区三区| 国产午夜精品免费一区二区三区| 亚洲欧洲视频在线| 日韩精品免费在线播放| 欧美成人激情图片网| 成人a在线观看| 亚洲人成毛片在线播放| 中文字幕综合一区| 都市激情亚洲色图| 91精品久久久久久久久青青| 米奇精品一区二区三区在线观看| 日韩av在线一区二区| 国产97色在线|日韩| 久久香蕉国产线看观看网| 国产z一区二区三区| 萌白酱国产一区二区| 亚洲福利在线视频| 最近2019年日本中文免费字幕| 亚洲欧美一区二区激情| 亚洲综合中文字幕68页| 亚洲japanese制服美女| 亚洲人成绝费网站色www| 91在线观看免费高清完整版在线观看| 久久精品国产一区二区电影| 日韩在线视频网| 91成人在线观看国产| 中文字幕精品一区二区精品| 欧美日韩亚洲网| 国产亚洲精品91在线| 丝袜情趣国产精品| 久热精品视频在线观看| 久久影视三级福利片| 欧美亚洲成人精品| 午夜伦理精品一区| 日产精品久久久一区二区福利| 一区二区成人精品| 九九综合九九综合| 国产亚洲精品一区二555| 日韩在线中文字幕| 亚洲精品免费在线视频| 欧美性猛交99久久久久99按摩| 中文字幕精品一区久久久久| 日韩中文第一页| 欧美大人香蕉在线| 91视频-88av| 国产精品久久99久久| 久久精品国产亚洲一区二区| 国产精品日韩精品| 欧洲成人午夜免费大片| 在线视频一区二区| 欧美激情综合色综合啪啪五月| 欧美成人亚洲成人日韩成人| 亚洲免费影视第一页| 亚洲国产精品成人精品| 亚洲在线www| 久久成人精品电影| 久久久国产视频91| 狠狠色狠色综合曰曰| 国产精品99久久久久久人| 精品久久久久久中文字幕一区奶水| 亚洲最大成人在线| 国产精品福利小视频| 亚洲精品视频二区| 亚洲美女在线看|