nsobject的那點事
社群會員jameshudw對nsobject類做的總結,希望對各位有所幫助。
文/cocoachina社群會員jameshudw
首先我們來看一下c語言中的struct的記憶體表示:
typedef struct intstruct
intstruct;
結構體在記憶體中的表示為:
00 00 00 0a
如果我們簡單的定義乙個int並賦值,這個int在記憶體中的表示為:
int i = 10;
00 00 00 0a
結構體和int在記憶體中的表示是一樣的!
如果我們定義的結構體更為複雜,有多個變數,那麼它們在記憶體中是依次排列的(不考慮大端小端的情況)。在記憶體中排列一致,導致intstruct和int可以相互轉換。
cfarrayref arrayref = //some value;
nsarray *array = (nsarray*)arratref;
我們回頭再看nsobject的定義,理解下為什麼objective-c稱之為objective-c.
@inte***ce nsobject
@inte***ce關鍵字告訴編譯器:請將nsobject作為objective-c的乙個類名,並將它轉換成乙個struct:
struct nsobject;
看到了吧,所有的object都是c的結構體。
我們再來看下class的定義:
typedef struct obj_class *class;
struct obj_class
objc_class包含了objc類所需的所有資訊,例如變數列表,方法列表,滿足的protocol等等。這些資訊可以通過gdb將感興趣的資訊列印出來.
我們注意到,nsobject和objc_class都有乙個isa變數,nsobject的isa描述它的元資訊(即object的類資訊),objc_class描述類的類資訊(即類的元資訊)。這樣,同object一樣,class也是一種object,它在obj_class的isa中可以記錄class method(用 + 宣告的方法)。
objc中的runtime reflection就是根據這資訊操作的。
方法:當你在為object定義方法時,例如:
@implementation myclass
- (void)somemethod:(nsstring*)param
@end
編譯器會相應的轉換為:
void [-somemethod:](id self, sel _cmd, nsstring *param){}
_cmd為方法的呼叫方(receiver), _cmd為方法簽名(跟你用@selector得到的一樣),後續為方法需要的引數。
當你呼叫方法時,objective-c會將方法呼叫都會轉成c的方法呼叫。例如當你在程式裡寫如下語句時:
[myclass somemethod:@"bytedance"]
會相應的轉換為:
objc_msgsend(myclass, @selector(somemethod:), @"bytedance")
@selector本質是乙個c string,唯一與c string不同的是在整個記憶體空間中,同一方法簽名的@selector的記憶體位址是相同的,這樣在比較方法簽名時候不需要採用同strcmp這麼耗時的操作,而通過比較@selector的記憶體位址即可。
如果呼叫方沒有找到相應的方法,會呼叫 [nsobject resolveinstancemethod]方法給呼叫方一次處理的機會
先寫這麼多,希望對大家有所幫助。
社群原帖:
this的那點事
對於很多初學者,this總是搞得我們暈頭轉向。現在,我就簡單的總結一下關於this的那點事。this在函式定義時經常是不能確定的,只有在函式執行的時候才能最終確定this的歸屬。this總是指向最後呼叫它的物件,那麼怎麼知道到底是誰呼叫的呢?其實很簡單,我們知道函式呼叫的其中一種方法就是利用call...
拓展的那點事
時間過得很快,又到了公司每年的拓展時間,今年公司拓展活動是安排在崇明島,因為時間關係自己有一些瑣事不能參加,至今心裡還有一絲的眷戀。拓展訓練不是簡單的娛樂和體育活動,它的中間融合了各種挑戰的元素,這些東西一般是在大學和工作中很難學到的,有時我們看了一些書就感覺自己知道和明白這些道理,但是遇到真真的事...
typedef的那點事
typedef struct node node,linklist 以上這段 幾乎在任何資料結構教材中都會出現,如此經典的一段 的理解還真是費了我一番功夫。之前學的是c 這種純正c風格的寫法幾乎沒有用到過。1.struct node 定義了乙個stuct node型別的結構體 c語言規定結構體型別為...