objc類與對(duì)象

每個(gè)objc對(duì)象內(nèi)都有這幾部分:1.對(duì)象方法list 2.成員變量list 3.屬性list 4.isa指針

首先父能,對(duì)象方法list runtime使用objc_msgSend(receiver, selector)對(duì)方法進(jìn)行調(diào)用 receiver是方法的調(diào)用者, selector則是方法 @selector其實(shí)是方法名 在調(diào)用方法時(shí)在receiver中的method list中找到該方法然后再找到它的IMP(實(shí)現(xiàn))捻脖,如果找不到的話這就會(huì)發(fā)生unrecognized selector而導(dǎo)致crash。當(dāng)然這時(shí)候也還有補(bǔ)救措施,這就是傳說(shuō)中的消息轉(zhuǎn)發(fā)。首先第一次是在+resolveInstanceMethod:或者 +resolveClassMethod: 在這里我們可以添加一個(gè)函數(shù)調(diào)用纸型,然后返回yes這樣安全了。如果沒有就進(jìn)行fast forwarding實(shí)現(xiàn)-forwardingTargetForSelector:方法進(jìn)行對(duì)象轉(zhuǎn)移梅忌,也就是改變方法的調(diào)用者绊袋。如果還沒有調(diào)用就-methodSignatureForSelector:通過這個(gè)函數(shù)進(jìn)行獲得參數(shù),在這里進(jìn)行簽名NSInvocation并發(fā)送-forwardInvocation:铸鹰,否則就會(huì)造成crash。對(duì)象方法列表存放在類對(duì)象中皂岔。


16.09.14補(bǔ)充

id objc_msgSend(id self, SEL op, ...) {

if?(!self)?return?nil;

IMP?imp?=?class_getMethodImplementation(self->isa,?SEL?op);

imp(self,?op,?...);?//調(diào)用這個(gè)函數(shù)蹋笼,偽代碼...

}

//查找IMP

IMP?class_getMethodImplementation(Class?cls,?SEL?sel)?{

if?(!cls?||?!sel)?return?nil;

IMP?imp?=?lookUpImpOrNil(cls,?sel);

if?(!imp)?return?_objc_msgForward;?//_objc_msgForward?用于消息轉(zhuǎn)發(fā)

return?imp;

}

IMP?lookUpImpOrNil(Class?cls,?SEL?sel)?{

if?(!cls->initialize())?{

_class_initialize(cls);

}

Class?curClass?=?cls;

IMP?imp?=?nil;

do?{?//先查緩存,緩存沒有時(shí)重建,仍舊沒有則向父類查詢

if?(!curClass)?break;

if?(!curClass->cache)?fill_cache(cls,?curClass);

imp?=?cache_getImp(curClass,?sel);

if?(imp)?break;

}?while?(curClass?=?curClass->superclass);

return?imp;

}


下一個(gè)就是成員變量list 我們一般申明變量的時(shí)候在前面加_,比如_var。在成員變量list中存放當(dāng)前類的實(shí)例變量以及所有父類的實(shí)例變量剖毯。

然后是屬性list 申明屬性用@property 一般來(lái)說(shuō)property=ivar+setter+getter圾笨。在申明屬性后,編譯器會(huì)自動(dòng)訪問這些屬性所需方法逊谋,這就是autosynthesis擂达。這是在編譯器進(jìn)行,所以編譯器里看不見代碼胶滋。假如我們要更改setter板鬓,getter的名字,就在申明時(shí)在填充如@property(getter=???,setter=set???)這樣就可以更改默認(rèn)的生成方法究恤。假如我們要更改默認(rèn)生成的成員變量名字就采用@synthesize俭令,如@synthesize darling = _myDarling。同時(shí)還有一個(gè)@dynamic部宿,它會(huì)告訴編譯器setter getter用戶自己實(shí)現(xiàn)抄腔,如果沒有實(shí)現(xiàn)這兩個(gè)方法時(shí)正常編譯是沒問題,就是在使用這個(gè)變量時(shí)就會(huì)crash理张。

isa指針在第一次看挺玄學(xué)的赫蛇,經(jīng)常看見但不太了解什么作用雾叭。先放一張圖悟耘。

眾所周知,每個(gè)類在調(diào)用之前會(huì)生成一個(gè)靜態(tài)對(duì)象拷况。一個(gè)類存放著它的superclass指針指向父類作煌,而isa指針 對(duì)象指向類對(duì)象 類對(duì)象的isa指針指向元對(duì)象,元對(duì)象的isa指針指向根元對(duì)象根類對(duì)象的superclass指向nil赚瘦,根對(duì)象在objc中為nsobject粟誓。在調(diào)用一個(gè)方法時(shí),通過isa指針找到對(duì)象所屬的類起意,然后通過類的方法列表以及其父類的方法列表找尋方法進(jìn)行調(diào)用鹰服,在進(jìn)行objc_msgSend時(shí)并沒有返回值,返回值都是具體的調(diào)用產(chǎn)生的揽咕,所以objc可以對(duì)nil進(jìn)行方法調(diào)用不會(huì)crash悲酷,是因?yàn)閷ふ覍?duì)象時(shí)isa指針就得到0返回值。元對(duì)象內(nèi)部存放著類方法列表亲善,而對(duì)象方法列表存儲(chǔ)在類對(duì)象中设易。

那么類方法和實(shí)例方法有何不同?類方法是屬于類對(duì)象的蛹头,所以只能給類對(duì)象調(diào)用顿肺,self也是指類對(duì)象戏溺,不能調(diào)用對(duì)象方法。實(shí)例方法是屬于實(shí)例對(duì)象屠尊,只能通過實(shí)例對(duì)象調(diào)用旷祸,self就是指實(shí)例對(duì)象,也可以調(diào)用類方法讼昆。

通過短暫了解對(duì)象的各種姿勢(shì)托享,我們來(lái)舉個(gè)栗子。

self = [super init];

這在重寫對(duì)象初始化時(shí)都會(huì)調(diào)用浸赫,但我們這時(shí)候調(diào)用[self class]和[super class]得出的結(jié)果會(huì)一樣嘛闰围?答案是一樣的。原因是根據(jù)super是一個(gè)magic keyword掺炭,它是個(gè)編譯器標(biāo)示符和self指向的是同一個(gè)對(duì)象接受者辫诅。super的方法調(diào)用的函數(shù)是objc_msgSendSuper(struct objc_super *super, SEL op, ...)

struct objc_super {

__unsafe_unretained?id?receiver;

__unsafe_unretained?Class?super_class;

};

第一個(gè)receiver類似objc_msgSend的receiver,第二個(gè)參數(shù)是當(dāng)前類的父類涧狮。在[self class]中objc_msgSend中self查找炕矮,沒有,最后通過父類查找在nsobject中找到得到當(dāng)前類者冤。而[super class]首先構(gòu)造結(jié)構(gòu)體objc_super肤视,第一個(gè)為self,所以查找到父類,然后在父類的方法列表中查找class涉枫,最后還是在nsobject的class中找到方法邢滑,而處理的對(duì)象還是self,所以兩者的結(jié)果相同~有點(diǎn)繞

如果有錯(cuò)漏愿汰,請(qǐng)一定告訴我困后,學(xué)習(xí)還在繼續(xù)!THX

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末衬廷,一起剝皮案震驚了整個(gè)濱河市摇予,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌吗跋,老刑警劉巖侧戴,帶你破解...
    沈念sama閱讀 219,039評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異跌宛,居然都是意外死亡酗宋,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,426評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門疆拘,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)蜕猫,“玉大人,你說(shuō)我怎么就攤上這事哎迄』赜遥” “怎么了稀颁?”我有些...
    開封第一講書人閱讀 165,417評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)楣黍。 經(jīng)常有香客問我,道長(zhǎng)棱烂,這世上最難降的妖魔是什么租漂? 我笑而不...
    開封第一講書人閱讀 58,868評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮颊糜,結(jié)果婚禮上哩治,老公的妹妹穿的比我還像新娘。我一直安慰自己衬鱼,他們只是感情好业筏,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,892評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著鸟赫,像睡著了一般蒜胖。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上抛蚤,一...
    開封第一講書人閱讀 51,692評(píng)論 1 305
  • 那天台谢,我揣著相機(jī)與錄音,去河邊找鬼岁经。 笑死朋沮,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的缀壤。 我是一名探鬼主播樊拓,決...
    沈念sama閱讀 40,416評(píng)論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼塘慕!你這毒婦竟也來(lái)了筋夏?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,326評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤苍糠,失蹤者是張志新(化名)和其女友劉穎叁丧,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體岳瞭,經(jīng)...
    沈念sama閱讀 45,782評(píng)論 1 316
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡拥娄,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,957評(píng)論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了瞳筏。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片稚瘾。...
    茶點(diǎn)故事閱讀 40,102評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖姚炕,靈堂內(nèi)的尸體忽然破棺而出摊欠,到底是詐尸還是另有隱情丢烘,我是刑警寧澤,帶...
    沈念sama閱讀 35,790評(píng)論 5 346
  • 正文 年R本政府宣布些椒,位于F島的核電站播瞳,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏免糕。R本人自食惡果不足惜赢乓,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,442評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望石窑。 院中可真熱鬧牌芋,春花似錦、人聲如沸松逊。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,996評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)经宏。三九已至犀暑,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間烛恤,已是汗流浹背母怜。 一陣腳步聲響...
    開封第一講書人閱讀 33,113評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留缚柏,地道東北人苹熏。 一個(gè)月前我還...
    沈念sama閱讀 48,332評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像币喧,于是被迫代替她去往敵國(guó)和親轨域。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,044評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容