The Objective-C language defers as many decisions as it can from compile time and link time to runtime. Whenever possible, it does things dynamically. This means that the language requires not just a compiler, but also a runtime system to execute the compiled code. The runtime system acts as a kind of operating system for the Objective-C language; it’s what makes the language work.
Objective-C語言盡可能多地推遲從編譯時
和鏈接時
到運(yùn)行時
的決策滚粟。只要有可能烙荷,它就會動態(tài)地執(zhí)行操作
司志。這意味著該語言不僅需要編譯器距芬,還需要運(yùn)行時系統(tǒng)來執(zhí)行編譯后的代碼疚颊。運(yùn)行時系統(tǒng)作為Objective-C語言的一種操作系統(tǒng)
;這就是語言的工作原理。
首先今天寫這篇博客是對學(xué)習(xí)的記錄
那么什么是運(yùn)行時?什么叫編譯時?
編譯時顧名思義就是正在編譯的時候.那啥叫編譯呢?
就是編譯器幫你把源代碼翻譯成機(jī)器能識別的代碼
.(當(dāng)然只是一般意義上這么說,實(shí)際上可能只是翻譯成某個中間狀態(tài)的語言)
那編譯時就是簡單的作一些翻譯工作,比如檢查老兄你有沒有粗心寫錯啥關(guān)鍵字了啊.有啥詞法分析,語法分析之類的過程.就像個老師檢查學(xué)生的作文中有沒有錯別字和病句一樣.如果發(fā)現(xiàn)啥錯誤編譯器就告訴你.如果你用微軟的VS的話,點(diǎn)下build.那就開始編譯,如果下面有errors或者warning信息,那都是編譯器檢查出來的.所謂這時的錯誤就叫編譯時錯誤,這個過程中做的啥類型檢查也就叫編譯時類型檢查,或靜態(tài)類型檢查(所謂靜態(tài)嘛就是沒把真把代碼放內(nèi)存中運(yùn)行起來,而只是把代碼當(dāng)作文本來掃描下).所以有時一些人說編譯時還分配內(nèi)存啥的肯定是錯誤的說法.所謂運(yùn)行時就是代碼跑起來了.被裝載到內(nèi)存中去了.(你的代碼保存在磁盤上沒裝入內(nèi)存之前是個死家伙.只有跑到內(nèi)存中才變成活的).而運(yùn)行時類型檢查就與前面講的編譯時類型檢查(或者靜態(tài)類型檢查)不一樣.不是簡單的掃描代碼.而是在內(nèi)存中做些操作,做些判斷.
對象的本質(zhì)
我現(xiàn)在就來測試 : 下面是一個LGPerson對象
LGPerson *p = [LGPerson new];
clang -rewrite-objc main.m -o mian.cpp
因?yàn)槲覀兌贾繭C底層是C,我們進(jìn)一步可以編譯C++代碼(重寫)
通過C++編譯 我的天啊. 9851
行代碼嚇我一哆嗦,不過沒關(guān)系.作為一名優(yōu)秀iOS底層開發(fā)人員,誰沒見過一萬行代碼
似的!況且很多我都不需要考慮,里面有很多結(jié)構(gòu)體,都是一些引入,還有很多函數(shù),也不是我們關(guān)心的,我們把文件拖到最下面
int main(int argc, const char * argv[]) {
/* @autoreleasepool */ { __AtAutoreleasePool __autoreleasepool;
LGPerson *p = ((LGPerson *(*)(id, SEL))(void *)objc_msgSend)((id)objc_getClass("LGPerson"), sel_registerName("new"));
LGStudent*s = ((LGStudent *(*)(id, SEL))(void *)objc_msgSend)((id)objc_getClass("LGStudent"), sel_registerName("new"));
((void (*)(id, SEL))(void *)objc_msgSend)((id)p, sel_registerName("run"));
((void (*)(id, SEL))(void *)objc_msgSend)((id)s, sel_registerName("walk"));
}
return 0;
}
這就有點(diǎn)熟悉了,這不是我們main
函數(shù)的編譯?
然后先不管下面的方法調(diào)用的編譯,我們?nèi)植檎?code>LGPerson
#ifndef _REWRITER_typedef_LGPerson
#define _REWRITER_typedef_LGPerson
typedef struct objc_object LGPerson;
typedef struct {} _objc_exc_LGPerson;
#endif
struct LGPerson_IMPL {
struct NSObject_IMPL NSObject_IVARS;
};
很明顯的一句話typedef struct objc_object LGPerson;
那么我們的LGPerson
就是objc_object類型的結(jié)構(gòu)體
~~~那么我們所說的對象預(yù)計都是objc_object類型的結(jié)構(gòu)體
!我們帶著好奇心繼續(xù)查看objc_object
struct objc_object {
Class _Nonnull isa __attribute__((deprecated));
};
非常熟悉的身形isa
這個時候我就想到了另外一個東西NSObject
typedef struct objc_object NSObject;
struct NSObject_IMPL {
Class isa;
};
我們的NSObject
的isa
是objc_object
結(jié)構(gòu)體重的屬性在我們實(shí)現(xiàn)NSObject
的時候只是對isa
的重寫~~~isa
也是我們后面后面學(xué)習(xí)非常重要的路線.比如我們編譯block
也能看到isa
,代表這個匿名函數(shù)也是對象,也重復(fù)符合萬物皆對象
的說法!!!