iOS runtime研究

structobjc_class {

Class isaOBJC_ISA_AVAILABILITY;

#if !__OBJC2__

Class super_classOBJC2_UNAVAILABLE;//父類

constchar*nameOBJC2_UNAVAILABLE;//類名

longversionOBJC2_UNAVAILABLE;//版本號,默認0

longinfoOBJC2_UNAVAILABLE;//類信息

longinstance_sizeOBJC2_UNAVAILABLE;//類實例變量大小

structobjc_ivar_list *ivarsOBJC2_UNAVAILABLE;//屬性列表

structobjc_method_list **methodListsOBJC2_UNAVAILABLE;//方法列表

structobjc_cache *cacheOBJC2_UNAVAILABLE;//經常調用的方法列表

structobjc_protocol_list *protocolsOBJC2_UNAVAILABLE;//協議列表

#endif

}OBJC2_UNAVAILABLE;

方法

-(void)test

{

//獲取屬性列表

unsignedintcount;

objc_property_t*propertyList =class_copyPropertyList([selfclass], &count);

for(NSIntegeri =0;i<count;i++)

{

constchar*property =property_getName(propertyList[i]);

NSLog(@"%@",[NSStringstringWithUTF8String:property]);

}

objc_property_tt =class_getProperty([selfclass],"str4");

//獲取方法列表

Method*methodList =class_copyMethodList([selfclass], &count);

for(NSIntegeri =0;i<count;i++)

{

Methodmethod = methodList[i];

NSLog(@"%@",NSStringFromSelector(method_getName(method)));

}

//獲取成員變量列表

Ivar*ivarList =class_copyIvarList([selfclass], &count);

for(NSIntegeri =0;i<count;i++)

{

Ivarivar = ivarList[i];

NSLog(@"%@",[NSStringstringWithUTF8String:ivar_getName(ivar)]);

}

//獲取協議列表

__unsafe_unretainedProtocol **protocolList =class_copyProtocolList([selfclass], &count);

for(NSIntegeri =0;i<count;i++)

{

Ivarivar = ivarList[i];

NSLog(@"%@",[NSStringstringWithUTF8String:ivar_getName(ivar)]);

}

}

方法調用

消息發送過程,objc_msgsend(id,SEL,var...)

首先在對象的類對象的chche,methodList以及父類對象的cache,methondList里尋找SEL對應的IMP

如果沒有找到,實現了方法//動態決議方法

+ (BOOL)resolveClassMethod:(SEL)name;?

?+ (BOOL)resolveInstanceMethod:(SEL)name;

并且在里面提供了相應的SEL,那就能正確運行,否則

跳到//消息轉發函數 ?讓別的對象去執行這個函數

- (id)forwardingTargetForSelector:(SEL)aSelector

如果未實現//將目標函數以其他形式執行

- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector

- (void)forwardInvocation:(NSInvocation *)anInvocation

否則到

- (void)doesNotRecognizeSelector:(SEL)aSelector

crash

簡單例子

voiddynamicMethodIMP(idself,SEL_cmd)

{

printf("SEL %s did not exist\n",sel_getName(_cmd));

}

//動態方法解析 ? 動態加方法

+(BOOL)resolveInstanceMethod:(SEL)sel

{

//if(sel==@selector(some))

//{

//class_addMethod([self class],sel,(IMP)dynamicMethodIMP,"v@:");

//return YES;

//

//}

return[superresolveInstanceMethod:sel];;

}

//轉交給其他類處理

-(id)forwardingTargetForSelector:(SEL)aSelector

{

//if(aSelector==@selector(some))

//{

//

//return [ViewController new];

//}

returnnil;

}

//完整消息轉發機制

- (NSMethodSignature*)methodSignatureForSelector:(SEL)aSelector {

NSMethodSignature*sig;

sig = [[ViewControllernew]methodSignatureForSelector:aSelector];

returnsig;

}

-(void)forwardInvocation:(NSInvocation*)anInvocation

{

idtarget = [ViewControllernew];

[anInvocationinvokeWithTarget:target];

}




SEL : 類成員方法的指針,但不同于C語言中的函數指針,函數指針直接保存了方法的地址,但SEL只是方法編號。

IMP:一個函數指針,保存了方法的地址

關聯對象

NSString*something =@"111";

UILabel*label = [UILabelnew];

objc_setAssociatedObject(something, &someKey, label,OBJC_ASSOCIATION_RETAIN);

UILabel*label1 =objc_getAssociatedObject(something, &someKey);

方法交換 method swizzling ?

void method_exchangeImplementations(Method m1, Method m2)

//放在load里是因為load只觸發一次,用dispatch_once也可以

+(void)load

{

MethodfromMethod =class_getInstanceMethod(self,@selector(viewDidLoad));

MethodtoMethod =class_getInstanceMethod(self,@selector(changeMethod));

if(!class_addMethod([selfclass],@selector(viewDidLoad),method_getImplementation(toMethod),method_getTypeEncoding(toMethod)))

{

method_exchangeImplementations(fromMethod,toMethod);

}

}

//這邊[self changeMethod];其實調用的是[self viewDidLoad];

-(void)changeMethod

{

NSLog(@"changeMethod");

[self changeMethod];

}

框架:JRSwizzle

參考http://www.cocoachina.com/ios/20150901/13173.html

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,406評論 6 538
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,034評論 3 423
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,413評論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,449評論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,165評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,559評論 1 325
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,606評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,781評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,327評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,084評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,278評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,849評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,495評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,927評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,172評論 1 291
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,010評論 3 396
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,241評論 2 375

推薦閱讀更多精彩內容

  • 轉至元數據結尾創建: 董瀟偉,最新修改于: 十二月 23, 2016 轉至元數據起始第一章:isa和Class一....
    40c0490e5268閱讀 1,753評論 0 9
  • 我們常常會聽說 Objective-C 是一門動態語言,那么這個「動態」表現在哪呢?我想最主要的表現就是 Obje...
    Ethan_Struggle閱讀 2,227評論 0 7
  • 本文轉載自:http://yulingtianxia.com/blog/2014/11/05/objective-...
    ant_flex閱讀 772評論 0 1
  • 參考鏈接: http://www.cnblogs.com/ioshe/p/5489086.html 簡介 Runt...
    樂樂的簡書閱讀 2,150評論 0 9
  • 轉載:http://yulingtianxia.com/blog/2014/11/05/objective-c-r...
    F麥子閱讀 756評論 0 2