美文网首页
10.isMemberOfClass,isKindOfClass

10.isMemberOfClass,isKindOfClass

作者: ProfessorFan | 来源:发表于2022-05-18 10:57 被阅读0次

    问题

    1.isMemberOfClass,isKindOfClass 底层实现
    2.练习题
    3.super 的本质

    答案

    1.isMemberOfClass,isKindOfClass 底层实现

    // 这个是对象方法,很明显就是判断 一个实例对象所指向的类对象是否 和 传入的对象是否一样
    - (BOOL)isMemberOfClass:(Class)cls {
        return [self class] == cls;
    }
    
    // 这个是对象方法,很明显就是判断 一个实例对象所指向的类对象是否 和 传入的对象是否一样 或者 是传入对象的子类
    
    - (BOOL)isKindOfClass:(Class)cls {
        for (Class tcls = [self class]; tcls; tcls = tcls->superclass) {
            if (tcls == cls) return YES;
        }
        return NO;
    }
    
    // 这个是类方法,很明显是判断一个类的元类对象 是否 和 传入的对象是否一样
    + (BOOL)isMemberOfClass:(Class)cls {
        return object_getClass((id)self) == cls;
    }
    
    // 这个是类方法,很明显是判断一个类的元类对象 是否 和 传入的对象是否一样 或者 是 传入的对象的子类
    + (BOOL)isKindOfClass:(Class)cls {
        for (Class tcls = object_getClass((id)self); tcls; tcls = tcls->superclass) {
            if (tcls == cls) return YES;
        }
        return NO;
    }
    

    2.练习题
    提示: NSObject 的元 类对象 的 superClass 指向 的是 NSObject 的类对象

            NSLog(@"%d", [[NSObject class] isKindOfClass:[NSObject class]]); // 结果为:  1
            NSLog(@"%d", [[NSObject class] isMemberOfClass:[NSObject class]]);// 结果为: 0
            NSLog(@"%d", [[MJPerson class] isKindOfClass:[MJPerson class]]);// 结果为:  0
            NSLog(@"%d", [[MJPerson class] isMemberOfClass:[MJPerson class]]);// 结果为:  0
    

    3.Super的本质

    这个是我编译ViewController 得到的 cpp 部分源码,可以看书,super 本质 是调用了
    objc_msgSendSuper() 方法里面涉及到了两个参数

    图解:


    super本质.png

    第一个参数 :一个结构体
    __rw_objc_super {
    self, // 当前的 viewController 实例对象
    class_getSuperclass(objc_getClass("ViewController")) // viewController 的 类对象的 父类
    }

    第二个参数: 方法名
    sel_registerName("viewDidLoad")

    static void _I_ViewController_viewDidLoad(ViewController * self, SEL _cmd) {
        ((void (*)(__rw_objc_super *, SEL))(void *)objc_msgSendSuper)((__rw_objc_super){(id)self, (id)class_getSuperclass(objc_getClass("ViewController"))}, sel_registerName("viewDidLoad"));
        id cls = ((Class (*)(id, SEL))(void *)objc_msgSend)((id)objc_getClass("MJPerson"), sel_registerName("class"));
        void *obj = &cls;
        ((void (*)(id, SEL))(void *)objc_msgSend)((id)obj, sel_registerName("print"));
    }
    

    相关文章

      网友评论

          本文标题:10.isMemberOfClass,isKindOfClass

          本文链接:https://www.haomeiwen.com/subject/yronurtx.html