類的動態建立(ro,rw)& 懶加載類和非懶加載類底層加載的區別 & 類和分類的搭配分析

1.一個參數取地址了,一個沒有,兩種寫法是同樣的,只是語法不一樣的問題。

2.元類的遞歸問題:

經過函數傳入,表,isa,若是存在返回cls元類,不存在返回c2是nil 面試

若是沒有下標idx,存一份,有則返回NX_,回到第二步驟api

3.面試題:類的建立 ro rw

(1)實例:

注意:

1.先添加成員變量再註冊內存,若是先註冊內存,就會調用changinfo,以下圖返回NO,沒法繼續往下走,沒法添加ivar // : 添加成員變量 1<<aligment // ivar - ro - ivarlist class_addIvar(LGPerson, "lgName", sizeof(NSString *), log2(sizeof(NSString *)), "@"); // : 註冊到內存 objc_registerClassPair(LGPerson);數組

// cls->ISA()->changeInfo(RW_CONSTRUCTED, RW_CONSTRUCTING | RW_REALIZING);
    // cls->changeInfo(RW_CONSTRUCTED, RW_CONSTRUCTING | RW_REALIZING);
複製代碼

2.:先添加set,get方法才能調用setValue forKey,不然報錯 沒法添加進去。 添加setter + getter 方法 class_addMethod(LGPerson, @selector(setSubject:), (IMP)lgSetter, "v@:@"); class_addMethod(LGPerson, @selector(subject), (IMP)lgName, "@@:");

// 開始使用
    id person = [LGPerson alloc];
    [person setValue:@"KC" forKey:@"lgName"];
    NSLog(@"%@",[person valueForKey:@"lgName"]);
複製代碼

ro - rw - 類的動態建立面試題

// 1: 動態建立類
    Class LGPerson = objc_allocateClassPair([NSObject class], "LGPerson", 0);
    // 2: 添加成員變量 1<<aligment
    // ivar - ro - ivarlist
    class_addIvar(LGPerson, "lgName", sizeof(NSString *), log2(sizeof(NSString *)), "@");
    // 3: 註冊到內存
    objc_registerClassPair(LGPerson);
    
    // cls->ISA()->changeInfo(RW_CONSTRUCTED, RW_CONSTRUCTING | RW_REALIZING);
    // cls->changeInfo(RW_CONSTRUCTED, RW_CONSTRUCTING | RW_REALIZING);
   
    // 3.1 添加property - rw
    lg_class_addProperty(LGPerson, "subject");
    lg_printerProperty([LGTeacher class]);
    lg_printerProperty(LGPerson);

    // 3.2 添加setter  +  getter 方法
    class_addMethod(LGPerson, @selector(setSubject:), (IMP)lgSetter, "v@:@");
    class_addMethod(LGPerson, @selector(subject), (IMP)lgName, "@@:");

    // 開始使用
    id person = [LGPerson alloc];
    [person setValue:@"KC" forKey:@"lgName"];
    NSLog(@"%@",[person valueForKey:@"lgName"]);
    
    id teacher = [LGTeacher alloc];
    [teacher setValue:@"iOS" forKey:@"subject"];
    NSLog(@"%@",[teacher valueForKey:@"subject"]);
    
    [person setValue:@"master" forKey:@"subject"];
    NSLog(@"%@",[person valueForKey:@"subject"]);
複製代碼

相關api 的註釋

* 建立類對
 *superClass: 父類,傳Nil會建立一個新的根類
 *name: 類名
 *extraBytes: 0
 *return:返回新類,建立失敗返回Nil,若是類名已經存在,則建立失敗
  objc_allocateClassPair(<#Class  _Nullable __unsafe_unretained superclass#>, <#const char * _Nonnull name#>, <#size_t extraBytes#>)
 */


/**
 *添加成員變量
 *
 *cls 往哪一個類添加
 *name 添加的名字
 *size 大小
 *alignment 對齊處理方式
 *types 簽名
 *
 *這個函數只能在objc_allocateClassPair和objc_registerClassPair以前調用。不支持向現有類添加一個實例變量。
 *這個類不能是元類。不支持在元類中添加一個實例變量。
 *實例變量的最小對齊爲1 << align。實例變量的最小對齊依賴於ivar的類型和機器架構。對於任何指針類型的變量,請經過log2(sizeof(pointer_type))。
  class_addIvar(<#Class  _Nullable __unsafe_unretained cls#>, <#const char * _Nonnull name#>, <#size_t size#>, <#uint8_t alignment#>, <#const char * _Nullable types#>)
 */

/**
 *往內存註冊類
 *
 * cls 要註冊的類
 *
 * objc_registerClassPair(<#Class  _Nonnull __unsafe_unretained cls#>)
 */


/**
 *往類裏面添加方法
 *
 *cls 要添加方法的類
 *sel 方法編號
 *imp 函數實現指針
 *types 簽名
 *
 *class_addMethod(<#Class  _Nullable __unsafe_unretained cls#>, <#SEL  _Nonnull name#>, <#IMP  _Nonnull imp#>, <#const char * _Nullable types#>)
 */



/**
 *往類裏面添加屬性
 *
 *cls 要添加屬性的類
 *name 屬性名字
 *attributes 屬性的屬性數組。
 *attriCount 屬性中屬性的數量。
 *
 *class_addProperty(<#Class  _Nullable __unsafe_unretained cls#>, <#const char * _Nonnull name#>, <#const objc_property_attribute_t * _Nullable attributes#>, <#unsigned int attributeCount#>)
 */
複製代碼

4.懶加載類和非懶加載類的區別

屬非懶加載類直接走上節課的realizeClassWithoutSwift 去加載數據,懶加載類 在lookupimpOrforward 中 有 if (!cls->isRealized())判斷條件,若是用到時候沒有實現過則進入實現流程,若是實現過則跳過判斷,進行下面的流程。 if (!cls->isRealized()) { cls = realizeClassMaybeSwiftAndLeaveLocked(cls, runtimeLock); // runtimeLock may have been dropped but is now locked again }架構

5.類和分類的搭配分析

1.懶加載類 + 非懶加載分類

主類在發送消息的時候纔有 — 可是分類提早了 — 須要加載 —-read_image —addUnattacheCategoryForClass —可是沒有實現類 ——prepare_load_methods —提早實現了主類realizeClassWithoutSwift函數

2.非懶加載類 + 非懶加載分類

readImages — realizeClassWithoutSwift —— methodLizeClass — addUnattacheCategoryForClass —判斷主類是否實現了,可是這時候主類已經實現了,if(cls —> isRealize){ remethodizeClass }ui

加載分類進來spa

cls —-> demangleName () 用這個,不能用Name addUnattachedCategoryForClass(cat, cls, hi); const char *cname = ro->name; const char *oname = "LGTeacher";//LGTeacher if (cname && (strcmp(cname, oname) == 0)) { // printf("_read_images - _getObjc2ClassList 類名 :%s - %p\n",cname,cls); }指針

if(cls —> isRealize) { remethodizeClass(cls); classExists == YES; }code

分類沒有實現load —— 編譯處理 — data() —> rocdn

3.非懶加載類 + 懶加載分類

readImages — realizeClassWithoutSwift —— methodLizeClass — 不須要添加表 ——直接 data() ——> ro

4.懶加載類 + 懶加載分類

消息發送的時候 ——lookupImpOrForward —— realizeClassWithoutSwift —— methodLizeClass — addUnattacheCategoryForClass 不進來 ——直接走data()

相關文章
相關標籤/搜索