Runtime底層原理之isa解讀

Snip20190816_6.png

前一篇講解了一下Runtime的底層原理,objc_msgSend的消息發(fā)送流程展箱;其實(shí)學(xué)習(xí)Runtime旨枯,首先要了解它底層的一些常用數(shù)據(jù)結(jié)構(gòu),比如isa指針析藕;在arm64架構(gòu)之前召廷,isa就是一個(gè)普通的指針凳厢,存儲(chǔ)著Class、Meta-Class對(duì)象的內(nèi)存地址竞慢;從arm64架構(gòu)開(kāi)始先紫,對(duì)isa進(jìn)行了優(yōu)化,變成了一個(gè)共用體(union)結(jié)構(gòu)筹煮,還使用位域來(lái)存儲(chǔ)更多的信息遮精。

共用體:

共用體把幾種不同數(shù)據(jù)類型的變量存放在同一塊內(nèi)存里。共用體中的變量共享同一塊內(nèi)存败潦。
union的主要特征有:

  • union中可以定義多個(gè)成員本冲,union的大小由最大的成員的大小決定;
  • union成員共享同一塊大小的內(nèi)存劫扒,一次只能使用其中的一個(gè)成員檬洞;
  • 對(duì)union某一個(gè)成員賦值,會(huì)覆蓋其他成員的值(但前提是成員所占字節(jié)數(shù)相同沟饥,當(dāng)成員所占字節(jié)數(shù)不同時(shí)只會(huì)覆蓋相應(yīng)字節(jié)上的值添怔,比如對(duì)char成員賦值就不會(huì)把整個(gè)int成員覆蓋掉,因?yàn)閏har只占一個(gè)字節(jié)贤旷,而int占四個(gè)字節(jié))广料;
  • union量的存放順序是所有成員都從低地址開(kāi)始存放的。

isa的結(jié)構(gòu)如下:

union isa_t 
{
    isa_t() { }
    isa_t(uintptr_t value) : bits(value) { }

    Class cls;
    uintptr_t bits;

#if SUPPORT_PACKED_ISA

# if __arm64__
#   define ISA_MASK        0x0000000ffffffff8ULL        //這個(gè)很重要后面會(huì)講到??
#   define ISA_MAGIC_MASK  0x000003f000000001ULL
#   define ISA_MAGIC_VALUE 0x000001a000000001ULL
    struct {
        uintptr_t nonpointer        : 1;
        uintptr_t has_assoc         : 1;
        uintptr_t has_cxx_dtor      : 1;
        uintptr_t shiftcls          : 33; // MACH_VM_MAX_ADDRESS 0x1000000000
        uintptr_t magic             : 6;
        uintptr_t weakly_referenced : 1;
        uintptr_t deallocating      : 1;
        uintptr_t has_sidetable_rc  : 1;
        uintptr_t extra_rc          : 19;
#       define RC_ONE   (1ULL<<45)
#       define RC_HALF  (1ULL<<18)
    };

# elif __x86_64__
...下面代碼省略不做重點(diǎn)介紹了??

};

isa參數(shù)詳解

  • nonpointer:
    0幼驶,代表普通的指針艾杏,存儲(chǔ)著Class、Meta-Class對(duì)象的內(nèi)存地址
    1盅藻,代表優(yōu)化過(guò)购桑,使用位域存儲(chǔ)更多的信息
  • has_assoc:是否有設(shè)置過(guò)關(guān)聯(lián)對(duì)象,如果沒(méi)有氏淑,釋放時(shí)會(huì)更快
  • has_cxx_dtor:是否有C++的析構(gòu)函數(shù)(.cxx_destruct)其兴,如果沒(méi)有,釋放時(shí)會(huì)更快
  • shiftcls:存儲(chǔ)著Class夸政、Meta-Class對(duì)象的內(nèi)存地址信息
  • magic:用于在調(diào)試時(shí)分辨對(duì)象是否未完成初始化
  • weakly_referenced:是否有被弱引用指向過(guò)元旬,如果沒(méi)有,釋放時(shí)會(huì)更快
  • deallocating:對(duì)象是否正在釋放
  • extra_rc:表示該對(duì)象的引用計(jì)數(shù)值守问,實(shí)際上是引用計(jì)數(shù)值減 1匀归,例如,如果對(duì)象的引用計(jì)數(shù)為 10耗帕,那么 extra_rc 為 9穆端。如果引用計(jì)數(shù)大于 10,則需要使用到下面的 has_sidetable_rc仿便。
  • has_sidetable_rc:當(dāng)對(duì)象引用計(jì)數(shù)大于 10 時(shí)体啰,則has_sidetable_rc 的值為 1攒巍,那么引用計(jì)數(shù)會(huì)存儲(chǔ)在一個(gè)叫 SideTable 的類的屬性中,這是一個(gè)散列表荒勇。原文鏈接

扯了這么多到底什么是isa?官方介紹是這樣的:
Every object is connected to the run-time system through itsisa instance variable, inherited from the NSObject class.isa identifies the object's class; it points to a structurethat's compiled from the class definition. Through isa, anobject can find whatever information it needs at run timesuch asits place in the inheritance hierarchy, the size and structure ofits instance variables, and the location of the methodimplementations it can perform in response to messages.
(每個(gè)對(duì)象都通過(guò)從NSObject類繼承的實(shí)例變量itsisa連接到運(yùn)行時(shí)系統(tǒng)柒莉。isa標(biāo)識(shí)對(duì)象的類;它指向一個(gè)從類定義編譯而來(lái)的結(jié)構(gòu)。通過(guò)isa沽翔,一個(gè)對(duì)象可以在運(yùn)行時(shí)找到它需要的任何信息兢孝,比如它在繼承層次結(jié)構(gòu)中的位置、它的實(shí)例變量的大小和結(jié)構(gòu)仅偎,以及它在響應(yīng)消息時(shí)可以執(zhí)行的methodimplementations的位置跨蟹。)

一個(gè)對(duì)象(Object)的isa指向了這個(gè)對(duì)象的類(Class),而這個(gè)對(duì)象的類(Class)的isa指向了metaclass橘沥。這樣我們就可以找到靜態(tài)方法和變量了窗轩。Objective-C的運(yùn)行時(shí)是動(dòng)態(tài)的,它能讓你在運(yùn)行時(shí)為類添加方法或者去除方法以及使用反射(反射什么鬼座咆?傳送門(mén))品姓。

講isa就一定會(huì)提到metaclass,這里先提一下什么是metaclass?

  • meta-class是一個(gè)類對(duì)象的類
  • 當(dāng)我們向一個(gè)對(duì)象發(fā)送消息時(shí)箫措,runtime會(huì)在這個(gè)對(duì)象所屬的這個(gè)類的方法列表中查找方法;而向一個(gè)類發(fā)送消息時(shí)衬潦,會(huì)在這個(gè)類的meta-class的方法列表中查找斤蔓。
  • meta-class 是必須的,因?yàn)樗鼮橐粋€(gè) Class 存儲(chǔ)類方法镀岛。每個(gè)Class都必須有一個(gè)唯一的 meta-class弦牡,因?yàn)槊總€(gè)Class的類方法基本不可能完全相同。

問(wèn)題提出:iOS中有靜態(tài)方法與動(dòng)態(tài)方法漂羊,那么兩種方法的異同是什么驾锰?(問(wèn)題來(lái)源:腳本之家-lqh )

因?yàn)槊總€(gè)對(duì)象都由相應(yīng)的數(shù)據(jù)結(jié)構(gòu)與方法相構(gòu)成,一個(gè)程序可能有多個(gè)屬于同一個(gè)類的對(duì)象走越,而每個(gè)對(duì)象的數(shù)據(jù)結(jié)構(gòu)應(yīng)該是不一的椭豫,但方法是相同的,若為每個(gè)對(duì)象開(kāi)辟內(nèi)存空間來(lái)存儲(chǔ)方法旨指,必然是對(duì)內(nèi)存空間極大的浪費(fèi)赏酥。因此apple是通過(guò)類對(duì)象與元類來(lái)解決這個(gè)問(wèn)題的。

對(duì)象的底層實(shí)際上就是結(jié)構(gòu)體谆构,其有兩個(gè)重要的指針裸扶,一個(gè)是isa指針,一個(gè)是super指針搬素。
isa指針:負(fù)責(zé)指向類對(duì)象呵晨,用來(lái)表明自己是什么類類型魏保,并能調(diào)用類對(duì)象中的動(dòng)態(tài)方法。
super指針:表示對(duì)象的繼承關(guān)系摸屠,指向父類谓罗,從而能調(diào)用父類的相應(yīng)方法。
類對(duì)象:類對(duì)象是由元類生成的對(duì)象餐塘,負(fù)責(zé)存儲(chǔ)動(dòng)態(tài)方法妥衣,動(dòng)態(tài)方法在編譯器是不確定的,因此編譯器也無(wú)法檢測(cè)與動(dòng)態(tài)方法相關(guān)的錯(cuò)誤戒傻,動(dòng)態(tài)方法的調(diào)用是在運(yùn)行期中通過(guò)消息機(jī)制來(lái)執(zhí)行的税手,因此也只有運(yùn)行期才會(huì)報(bào)錯(cuò)。


image.png

結(jié)論:

兩者的差異包括:

  1. 方法列表是區(qū)分開(kāi)的需纳,分別存儲(chǔ)在類對(duì)象與元類中芦倒。
  2. 動(dòng)態(tài)方法是在運(yùn)行期中調(diào)用,編譯器無(wú)法檢測(cè)錯(cuò)誤不翩,靜態(tài)方法是在編譯器就確定兵扬,編譯器能檢測(cè)錯(cuò)誤。
  3. 動(dòng)態(tài)方法由對(duì)象調(diào)用口蝠,靜態(tài)方法由類調(diào)用器钟,因?yàn)檎{(diào)用方法是通過(guò)isa和super指針實(shí)現(xiàn)的。因此對(duì)象只能調(diào)用類對(duì)象的方法妙蔗,而類對(duì)像能調(diào)用元類的方法傲霸。
isa.png

這張圖描述如下:

  • 類的實(shí)例對(duì)象的 isa 指向它的類;類的 isa 指向該類的 metaclass眉反;
  • 類的 super_class 指向其父類昙啄,如果該類為根類則值為 NULL;
  • metaclass 的 isa 指向根 metaclass寸五,如果該 metaclass 是根 metaclass則指向自身梳凛;
  • metaclass 的 super_class 指向父 metaclass,如果該 metaclass 是根 metaclass則指向該 metaclass 對(duì)應(yīng)的類梳杏;
  • Object-C 為每個(gè)類的定義生成兩個(gè) objc_class 韧拒,一個(gè)普通的 class,另一個(gè)即metaclass十性。我們可以在運(yùn)行期創(chuàng)建這兩個(gè) objc_class 數(shù)據(jù)結(jié)構(gòu)叭莫,然后使用 objc_addClass將 class注冊(cè)到運(yùn)行時(shí)系統(tǒng)中,以此實(shí)現(xiàn)動(dòng)態(tài)地創(chuàng)建一個(gè)新的類烁试。

為什么這里說(shuō)生成兩個(gè) objc_class 雇初,從前面metaclass就可以了解一二了。講到這里减响,大家可能很疑惑isa到底是怎么指向類的靖诗,解釋如下:isa里面存儲(chǔ)各種信息郭怪,是一個(gè)共用體,其中shiftcls 33位才是用來(lái)存放地址,通過(guò)&ISA_MASK就可以將33位的地址值取出來(lái),看圖分析理解更透徹:

isa圖解,來(lái)源于MJ

因?yàn)橄旅嬉玫絚lass 講解刊橘,我們先來(lái)看看 objc_class 的定義鄙才,然后來(lái)個(gè)實(shí)例和圖解進(jìn)行分析:

struct objc_class {
    Class _Nonnull isa  OBJC_ISA_AVAILABILITY;

#if !__OBJC2__
    Class _Nullable super_class                              OBJC2_UNAVAILABLE;
    const char * _Nonnull name                               OBJC2_UNAVAILABLE;
    long version                                             OBJC2_UNAVAILABLE;
    long info                                                OBJC2_UNAVAILABLE;
    long instance_size                                       OBJC2_UNAVAILABLE;
    struct objc_ivar_list * _Nullable ivars                  OBJC2_UNAVAILABLE;
    struct objc_method_list * _Nullable * _Nullable methodLists                    OBJC2_UNAVAILABLE;
    struct objc_cache * _Nonnull cache                       OBJC2_UNAVAILABLE;
    struct objc_protocol_list * _Nullable protocols          OBJC2_UNAVAILABLE;
#endif

} OBJC2_UNAVAILABLE;

稍微解釋一下各個(gè)參數(shù)的意思:

  • isa:是一個(gè)Class 類型的指針. 每個(gè)實(shí)例對(duì)象有個(gè)isa的指針,他指向?qū)ο蟮念悾鳦lass里也有個(gè)isa的指針, 指向meteClass(元類)促绵。元類保存了類方法的列表攒庵。當(dāng)類方法被調(diào)用時(shí),先會(huì)從本身查找類方法的實(shí)現(xiàn)败晴,如果沒(méi)有浓冒,元類會(huì)向他父類查找該方法。同時(shí)注意的是:元類(meteClass)也是類尖坤,它也是對(duì)象稳懒。元類也有isa指針,它的isa指針最終指向的是一個(gè)根元類(root meteClass).根元類的isa指針指向本身,這樣形成了一個(gè)封閉的內(nèi)循環(huán)慢味。
  • super_class:父類场梆,如果該類已經(jīng)是最頂層的根類,那么它為NULL。
  • version:類的版本信息,默認(rèn)為0
  • info:供運(yùn)行期使用的一些位標(biāo)識(shí)纯路。
  • instance_size:該類的實(shí)例變量大小
  • ivars:成員變量的數(shù)組

下面來(lái)個(gè)例子:

  1. 新建一個(gè)類Parent或油,繼承于NSObject, 里面有成員方法-(void)selectorP,類方法+(void)ClassSelectorP驰唬。
  2. 新建一個(gè)類Child顶岸,繼承于Parent,里面有成員方法-(void)selectorC, 類方法+(void)ClassSelectorC.

現(xiàn)在我們新建一個(gè)實(shí)例Child* child = [Chlid new];

  1. 當(dāng)我們調(diào)用[child class] 的時(shí)候定嗓,child就會(huì)通過(guò)isa指針去找到Child。
  2. 當(dāng)我們調(diào)用[child superclass]的時(shí)候萍桌,child 通過(guò)isa找到Child宵溅,再通過(guò)Child的isa,找到Parent上炎。
    對(duì)象方法
  3. 接著恃逻,調(diào)用[child SelectorC],child通過(guò)isa找到Child藕施,在Child的方法列表里面找到SelectorC寇损;
  4. 再試著調(diào)用[child SelectorP],child通過(guò)isa找到Child裳食,發(fā)現(xiàn)Child里面并沒(méi)有這個(gè)方法矛市,再通過(guò)Child的isa,找到Parent诲祸,在Parent里面的方法列表找到了SelectorP浊吏;
    類方法
  5. 再是類方法[Child ClassSelectorC]而昨,Child(請(qǐng)注意是類調(diào)用)通過(guò)isa找到Child的metaclass,在metaclass的方法列表里面找到了ClassSelectorC找田;
  6. 再試著調(diào)用[Child ClassSelectorP]歌憨,Child通過(guò)isa找到Child的metaclass,發(fā)現(xiàn)metaclass里面并沒(méi)有這個(gè)方法墩衙,通過(guò)metaclass里面的isa找到Parent的metaclass务嫡,在里面的方法列表找到了ClassSelectorP;
  7. 所有的元類最終繼承一個(gè)根元類漆改,根元類isa指針指向本身心铃,形成一個(gè)封閉的內(nèi)循環(huán)
    圖解如下:


    靈魂畫(huà)手??

isa基本就講完了,下面來(lái)個(gè)小李子再次加深理解:
NSArray *array = [[NSArray alloc] init]籽懦;流程剖析

  1. [NSArray alloc]先被執(zhí)行于个。先去NSArray中查找+alloc方法(類方法),因?yàn)镹SArray沒(méi)有+alloc方法暮顺,于是去父類NSObject去查找厅篓。
  2. 檢測(cè)NSObject是否響應(yīng)+alloc方法,發(fā)現(xiàn)響應(yīng)捶码,于是檢測(cè)NSArray類羽氮,并根據(jù)其所需的內(nèi)存空間大小開(kāi)始分配內(nèi)存空間,然后把isa指針指向NSArray類惫恼。同時(shí)档押,+alloc也被加進(jìn)cache列表里面。
  3. 接著祈纯,執(zhí)行-init方法令宿,如果NSArray響應(yīng)該方法,則直接將其加入cache腕窥;如果不響應(yīng)粒没,則去父類查找。
  4. 在后期的操作中簇爆,如果再以[[NSArray alloc] init]這種方式來(lái)創(chuàng)建數(shù)組癞松,則會(huì)直接從cache中取出相應(yīng)的方法,直接調(diào)用入蛆。

總結(jié):

  • isa是一個(gè)共用體响蓉;isa標(biāo)識(shí)對(duì)象的類;它指向一個(gè)從類定義編譯而來(lái)的結(jié)構(gòu)。通過(guò)isa哨毁,一個(gè)對(duì)象可以在運(yùn)行時(shí)找到它需要的任何信息枫甲,比如它在繼承層次結(jié)構(gòu)中的位置、它的實(shí)例變量的大小和結(jié)構(gòu),以及它在響應(yīng)消息時(shí)可以執(zhí)行的imp的位置言秸;
  • 也可以說(shuō)isa是一個(gè)Class 類型的指針软能,每個(gè)實(shí)例對(duì)象有個(gè)isa的指針,他指向?qū)ο蟮念惤Y(jié)構(gòu)。
  • Objective-C 2.0中的描述是:新的對(duì)象被創(chuàng)建举畸,其內(nèi)存同時(shí)被分配查排,實(shí)例變量也同時(shí)被初始化;對(duì)象的第一個(gè)實(shí)例變量是一個(gè)指向 該對(duì)象的類結(jié)構(gòu)的指針抄沮,叫做 isa跋核。通過(guò)該指針,對(duì)象可以訪問(wèn)它對(duì)應(yīng)的類以及相應(yīng)的父類叛买。

文章參考:
http://www.reibang.com/p/cf93dc9d2262
http://www.reibang.com/p/83b9f172c43c

最后編輯于
?著作權(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)離奇詭異捶箱,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)动漾,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,426評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)丁屎,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人旱眯,你說(shuō)我怎么就攤上這事晨川。” “怎么了删豺?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,417評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵共虑,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我呀页,道長(zhǎng)妈拌,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,868評(píng)論 1 295
  • 正文 為了忘掉前任赔桌,我火速辦了婚禮供炎,結(jié)果婚禮上渴逻,老公的妹妹穿的比我還像新娘疾党。我一直安慰自己,他們只是感情好惨奕,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,892評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布雪位。 她就那樣靜靜地躺著,像睡著了一般梨撞。 火紅的嫁衣襯著肌膚如雪雹洗。 梳的紋絲不亂的頭發(fā)上香罐,一...
    開(kāi)封第一講書(shū)人閱讀 51,692評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音时肿,去河邊找鬼庇茫。 笑死,一個(gè)胖子當(dāng)著我的面吹牛螃成,可吹牛的內(nèi)容都是我干的旦签。 我是一名探鬼主播,決...
    沈念sama閱讀 40,416評(píng)論 3 419
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼寸宏,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼宁炫!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起氮凝,我...
    開(kāi)封第一講書(shū)人閱讀 39,326評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤羔巢,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后罩阵,有當(dāng)?shù)厝嗽跇?shù)林里發(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
  • 文/蒙蒙 一享甸、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧梳侨,春花似錦蛉威、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,996評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春择示,著一層夾襖步出監(jiān)牢的瞬間束凑,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,113評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工栅盲, 沒(méi)想到剛下飛機(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)容

  • 首先說(shuō)明旗们,這篇文章幾乎都是抄錄的別人的博客,簡(jiǎn)書(shū)文章构灸,在此總結(jié)上渴,只是為了方便記憶和以后閱讀,如果有什么失禮的地方喜颁,...
    devCK凱閱讀 521評(píng)論 0 0
  • 首先說(shuō)明稠氮,這篇文章幾乎都是抄錄的別人的博客,簡(jiǎn)書(shū)文章半开,在此總結(jié)隔披,只是為了方便記憶和以后閱讀,如果有什么失禮的地方寂拆,...
    LiYaoPeng閱讀 4,956評(píng)論 1 14
  • 本文轉(zhuǎn)載自:http://southpeak.github.io/2014/10/25/objective-c-r...
    idiot_lin閱讀 935評(píng)論 0 4
  • 一奢米、前言 OC是一門(mén)動(dòng)態(tài)語(yǔ)言,它將很多靜態(tài)語(yǔ)言在編譯和鏈接時(shí)期做的事放到了運(yùn)行時(shí)來(lái)處理纠永。即說(shuō)明OC需要一個(gè)編譯器和...
    雨潤(rùn)聽(tīng)潮閱讀 706評(píng)論 1 0
  • 1.理解NSObject和元類 1.1 在OC中的對(duì)象和類是什么 對(duì)象是在objc.h中定義的 類是在runtim...
    HWenj閱讀 924評(píng)論 0 3