美文网首页
笔记07 msgSend

笔记07 msgSend

作者: PPFSaber | 来源:发表于2021-03-16 21:06 被阅读0次
    image.png
    /*
     [super message]的底层实现
     1.消息接收者仍然是子类对象
     2.从父类开始查找方法的实现
     */
    
    struct objc_super {
        __unsafe_unretained _Nonnull id receiver; // 消息接收者
        __unsafe_unretained _Nonnull Class super_class; // 消息接收者的父类
    };
    
    - (void)run
    {
        // super调用的receiver仍然是MJStudent对象
        [super run];
        
        
    //    struct objc_super arg = {self, [MJPerson class]};
    //
    //    objc_msgSendSuper(arg, @selector(run));
    //
    //
    //    NSLog(@"MJStudet.......");
        
    }
    
    - (instancetype)init
    {
        if (self = [super init]) {
            NSLog(@"[self class] = %@", [self class]); // MJStudent
            NSLog(@"[self superclass] = %@", [self superclass]); // MJPerson
    
            NSLog(@"--------------------------------");
    
            // objc_msgSendSuper({self, [MJPerson class]}, @selector(class));
            NSLog(@"[super class] = %@", [super class]); // MJStudent
            NSLog(@"[super superclass] = %@", [super superclass]); // MJPerson
        }
        return self;
    }
    
    @end
    
     class  superclass 方法的底层实现
    //@implementation NSObject
    //
    //- (Class)class
    //{
    //    return object_getClass(self);
    //}
    //
    //- (Class)superclass
    //{
    //    return class_getSuperclass(object_getClass(self));
    //}
    //
    //@end
    
    
    
    //        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
            
            
            // 这句代码的方法调用者不管是哪个类(只要是NSObject体系下的),都返回YES
            NSLog(@"%d", [NSObject isKindOfClass:[NSObject class]]); // 1
            NSLog(@"%d", [NSObject isMemberOfClass:[NSObject class]]); // 0
            NSLog(@"%d", [MJPerson isKindOfClass:[MJPerson class]]); // 0
            NSLog(@"%d", [MJPerson isMemberOfClass:[MJPerson class]]); // 0
            
            
    //        id person = [[MJPerson alloc] init];
            
    //        NSLog(@"%d", [person isMemberOfClass:[MJPerson class]]);//1
    //        NSLog(@"%d", [person isMemberOfClass:[NSObject class]]);//0
            
    //        NSLog(@"%d", [person isKindOfClass:[MJPerson class]]);//1
    //        NSLog(@"%d", [person isKindOfClass:[NSObject class]]);//1
            
            
    //        NSLog(@"%d", [MJPerson isMemberOfClass:object_getClass([MJPerson class])]);//1
    //        NSLog(@"%d", [MJPerson isKindOfClass:object_getClass([NSObject class])]);//1
            
    //        NSLog(@"%d", [MJPerson isKindOfClass:[NSObject class]]);//1  因为 最后调用的是 元类 NSObject的superclass 的时候 指向的是 NSObject 的class 对象,最后获取到的是 [NSObject class] 对象,正好等于参数[NSObject class]
    
    NSObject  底层 实现
    - (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;
    }
    
    
    
    
    NSObject *obj2 = [[NSObject alloc]init];
    
      id cls = [MJPerson class];
    
        void *obj = &cls;
    
        [(__bridge id)obj print];
    /*
     1.print为什么能够调用成功?
     
     2.为什么self.name变成了ViewController等其他内容
     */
    

    内存结构


    image.png
    image.png image.png

    相当于 _name 的预期地址和 obj2 的地址 重合了

    相关文章

      网友评论

          本文标题:笔记07 msgSend

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