一.isa指針
要認(rèn)識(shí)什么是isa指針译荞,我們得先明確一點(diǎn):
在Objective-C中,任何類的定義都是對(duì)象。類和類的實(shí)例(對(duì)象)沒有任何本質(zhì)上的區(qū)別。任何對(duì)象都有isa指針茫死。
那么什么是類呢?在xcode中用快捷鍵Shift+Cmd+O 打開文件objc.h 能看到類的定義:
可以看出:
Class 是一個(gè) objc_class 結(jié)構(gòu)類型的指針, id是一個(gè) objc_object 結(jié)構(gòu)類型的指針.
我們再來看看 objc_class 的定義:
稍微解釋一下各個(gè)參數(shù)的意思:
isa:【***Object-C對(duì)類對(duì)象與實(shí)例對(duì)象中的 isa 所指向的類結(jié)構(gòu)作了不同的命名:類對(duì)象中的 isa 指向類結(jié)構(gòu)被稱作 metaclass履羞,metaclass 存儲(chǔ)類的static類成員變量與static類成員方法(+開頭的方法)峦萎;實(shí)例對(duì)象中的 isa 指向類結(jié)構(gòu)稱作 class(普通的),class 結(jié)構(gòu)存儲(chǔ)類的普通成員變量與普通成員方法(-開頭的方法)忆首。***】是一個(gè)Class 類型的指針. 每個(gè)實(shí)例對(duì)象有個(gè)isa的指針,他指向?qū)ο蟮念惏疲鳦lass里也有個(gè)isa的指針, 指向meteClass(元類)。元類保存了類方法的列表糙及。當(dāng)類方法被調(diào)用時(shí)详幽,先會(huì)從本身查找類方法的實(shí)現(xiàn),如果沒有浸锨,元類會(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ù)組
再來看看各個(gè)類實(shí)例變量的繼承關(guān)系:
每一個(gè)對(duì)象本質(zhì)上都是一個(gè)類的實(shí)例宇姚。其中類定義了成員變量和成員方法的列表匈庭。對(duì)象通過對(duì)象的isa指針指向類。
每一個(gè)類本質(zhì)上都是一個(gè)對(duì)象浑劳,類其實(shí)是元類(meteClass)的實(shí)例阱持。元類定義了類方法的列表。類通過類的isa指針指向元類魔熏。
所有的元類最終繼承一個(gè)根元類衷咽,根元類isa指針指向本身鸽扁,形成一個(gè)封閉的內(nèi)循環(huán)。
二.runtime 機(jī)制
runtime:指一個(gè)程序在運(yùn)行(或者在被執(zhí)行)的狀態(tài)镶骗。也就是說桶现,當(dāng)你打開一個(gè)程序使它在電腦上運(yùn)行的時(shí)候,那個(gè)程序就是處于運(yùn)行時(shí)刻鼎姊。在一些編程語言中骡和,把某些可以重用的程序或者實(shí)例打包或者重建成為“運(yùn)行庫"。這些實(shí)例可以在它們運(yùn)行的時(shí)候被連接或者被任何程序調(diào)用相寇。
objective-c中runtime:是一套比較底層的純C語言API, 屬于1個(gè)C語言庫, 包含了很多底層的C語言API慰于。 在我們平時(shí)編寫的OC代碼中, 程序運(yùn)行過程時(shí), 其實(shí)最終都是轉(zhuǎn)成了runtime的C語言代碼。
runtime的應(yīng)用:
1.動(dòng)態(tài)創(chuàng)建一個(gè)類(比如KVO的底層實(shí)現(xiàn))
2.動(dòng)態(tài)地為某個(gè)類添加屬性\方法, 修改屬性值\方法
3.遍歷一個(gè)類的所有成員變量(屬性)\所有方法
實(shí)質(zhì)上唤衫,以上的是通過相關(guān)方法來獲取對(duì)象或者類的isa指針來實(shí)現(xiàn)的婆赠。
相關(guān)函數(shù)
1.? 增加
增加函數(shù):class_addMethod
增加實(shí)例變量:class_addIvar
增加屬性:@dynamic標(biāo)簽,或者class_addMethod佳励,因?yàn)閷傩云鋵?shí)就是由getter和setter函數(shù)組成
增加Protocol:class_addProtocol (說實(shí)話我真不知道動(dòng)態(tài)增加一個(gè)protocol有什么用,-_-!!)
2.? 獲取
獲取函數(shù)列表及每個(gè)函數(shù)的信息(函數(shù)指針休里、函數(shù)名等等):class_getClassMethod method_getName ...
獲取屬性列表及每個(gè)屬性的信息:class_copyPropertyList property_getName
獲取類本身的信息,如類名等:class_getName class_getInstanceSize
獲取變量列表及變量信息:class_copyIvarList
獲取變量的值
3.? ? 替換
將實(shí)例替換成另一個(gè)類:object_setClass
替換類方法的定義:class_replaceMethod
4.其他常用方法:
交換兩個(gè)方法的實(shí)現(xiàn):method_exchangeImplementations.
設(shè)置一個(gè)方法的實(shí)現(xiàn):method_setImplementation.