Runtime

isa 指針

isa 是一個(gè) Class 類型的指針。
實(shí)例中:每個(gè)實(shí)例對象有一個(gè) isa 指針,它指向?qū)嵗龑ο蟮念悺?br> 類中:Class 里也有一個(gè) isa 的指針,指向 meteClass(元類)。
元類:元類保存類的方法列表。當(dāng)類方法被調(diào)用時(shí),先回從本身類查找方法的實(shí)現(xiàn)。如果沒有,元類會像其父類查找該方法。同時(shí)注意的是:元類也是類,它也是對象。元類也有 isa 指針,它的 isa 指針最終指向的是一個(gè)根元類。根元類的 isa 指針指向本身,它形成了一個(gè)封閉的內(nèi)循環(huán)。

Runtime 的數(shù)據(jù)結(jié)構(gòu)

  • id 類型
  struct objc_object{
        Class isa;
  };
  • Class 類型
    struct objc_class{
        Class isa;
    }
  • NSObject 類型
    struct objc_class{
        Class isa;
    }
  • 對象內(nèi)存
    Class isa;
    NSString *name;
    NSUinteger age;

Runtime 的消息機(jī)制

    [obj xxx];  編譯時(shí)---> objc_msgSend(obj,"xxx");

函數(shù)的定義

  • 操作對象,方法一般以 object_ 開頭
  • 操作類,方法一般以 class_ 開頭
  • 操作類or對象的方法,一般以 method_ 開頭
  • 操作成員變量,方法一般以 ivar_ 開頭
  • 操作屬性,方法一般以 property_ 開頭
  • 操作協(xié)議,方法一般以 protocol_ 開頭

由此,可以看出以 objc_ 開頭的方法是 runtime 最終的管家,可以獲取內(nèi)存中,類的加載信息列表、關(guān)聯(lián)對象、和關(guān)聯(lián)屬性等操作。

字典轉(zhuǎn)模型

有些場景中,模型的屬性與服務(wù)器端回傳的參數(shù)一致(服務(wù)器字段定義比較規(guī)范的)

  • 為了方便高效,不用在每一個(gè)數(shù)據(jù)模型中都手動去設(shè)置,減少工作量,我會用到一些 runtime 中的動態(tài)獲取屬性,動態(tài)賦值。

- (instancetype)initWithDictionary:(NSDidctionary *)dictionary{
   if (dictionary != nil){
        unsigned int count = 0;
        // 獲取屬性列表
        Ivar *ivarList = class_copyIvarList(self.class, &count);
        // 遍歷
        for (int i = 0; i < count; i++){
           Ivar theVar = ivarList[i];
           // 取出每個(gè)元素的 屬性名字,轉(zhuǎn)換成字典中的 Key
           const char *propertyName = ivar_getName(theVar);
           NSString *key = [NSString stringWithUTF8String:propertyName];
           // 獲取字典中的對應(yīng)屬性的值,由于屬性是由下劃線開頭,所以去掉下劃線
           id value = [dictionary objectForKey:[key stringByReplacingOccurrencesOfString:@"_" withString:@""]];
           // 為對應(yīng)屬性賦值
           object_setIvar(self.class,theVar,value);
        }
   }
    return self;
}

交換方法 or 動態(tài)添加方法

方法交換的實(shí)現(xiàn)一般寫在類的 load 方法里面,而 initialize 有可能調(diào)用多次

//創(chuàng)建一個(gè) category,在 load 方法中
+(void)load{
    Method originalMethod = class_getInstanceMethod(self.class,@selector(navigationBar:shouldPopItem:));
    Method newMethod = class_getInstanceMethod(self.class,@selector(xxx_navigationBar:shouldPopItem:));
    
    BOOL didAddMethod = class_addMethod()
}

屬性關(guān)聯(lián)

未完待續(xù)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容