类的动态建立(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()

相关文章
相关标签/搜索