Super

作者: comsubin | 来源:发表于2019-06-03 14:28 被阅读0次
    @interface person : NSObject
    
    @end
    
    @interface student : person
    
    @end
    
    @implementation student
    
    - (instancetype)init
    {
        self = [super init];
        if (self) {
            
            NSLog(@"%@---\n",[self class]);
            NSLog(@"%@---\n",[self superclass]);
            NSLog(@"%@---\n",[super class]);
            NSLog(@"%@---\n",[super superclass]);
        }
        return self;
    }
    
    @end
    
     Super[2393:41718] student---
     Super[2393:41718] person---
     Super[2393:41718] student---
     Super[2393:41718] person---
    

    先写个run方法 student继承然后重写,编译为c++文件.

    - (void)run{
        [super run];
    
        ((void (*)(__rw_objc_super *, SEL))(void *)objc_msgSendSuper)((__rw_objc_super){(id)self, (id)class_getSuperclass(objc_getClass("student"))}, sel_registerName("run"));
    }
    

    super 被转换成 objc_msgSendSuper,里面包含了一个objc_super的结构体.

    /// Specifies the superclass of an instance. 
    struct objc_super {
        __unsafe_unretained _Nonnull id receiver;
        __unsafe_unretained _Nonnull Class super_class;
    };
    
    /** 
     * Sends a message with a simple return value to the superclass of an instance of a class.
     * 
     * @param super A pointer to an \c objc_super data structure. Pass values identifying the
     *  context the message was sent to, including the instance of the class that is to receive the
     *  message and the superclass at which to start searching for the method implementation.
     * @param op A pointer of type SEL. Pass the selector of the method that will handle the message.
     * @param ...
     *   A variable argument list containing the arguments to the method.
     * 
     * @return The return value of the method identified by \e op.
     * 
     * @see objc_msgSend
     */
    OBJC_EXPORT id _Nullable
    objc_msgSendSuper(struct objc_super * _Nonnull super, SEL _Nonnull op, ...)
        OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0);
    

    objc_super 有2个成员,一个是消息接收者,一个父类, objc_msgSendSuper方法是从父类的方法列表开始寻找.消息接收者还是self.而class的方法实现都是NSObject,查看源码实现:

    - (Class)class{
        return object_getClass(self);
    }
    
    - (Class)superclass{
        return class_getSuperclass(object_getClass(self));
    }
    

    所有无论是[sefl class]还是[ super class],输出的都是student;

    ex: isKindOfClassisMemberOfClass

    + (Class)class {
        return self;
    }
    
    - (Class)class {
        return object_getClass(self);
    }
    
    + (Class)superclass {
        return self->superclass;
    }
    
    - (Class)superclass {
        return [self class]->superclass;
    }
    
    + (BOOL)isMemberOfClass:(Class)cls {
        return object_getClass((id)self) == cls;
    }
    
    - (BOOL)isMemberOfClass:(Class)cls {
        return [self class] == cls;
    }
    
    + (BOOL)isKindOfClass:(Class)cls {
        for (Class tcls = object_getClass((id)self); tcls; tcls = tcls->superclass) {
            if (tcls == cls) return YES;
        }
        return NO;
    }
    
    - (BOOL)isKindOfClass:(Class)cls {
        for (Class tcls = [self class]; tcls; tcls = tcls->superclass) {
            if (tcls == cls) return YES;
        }
        return NO;
    }
    
            NSLog(@"%d----\n",[[NSObject class]isKindOfClass:[NSObject class]]);
            NSLog(@"%d----\n",[[NSObject class]isMemberOfClass:[NSObject class]]);
            NSLog(@"%d----\n",[[student class]isKindOfClass:[student class]]);
            NSLog(@"%d----\n",[[student class]isMemberOfClass:[student class]]);
            
    

    [NSObject class]isKindOfClass:[NSObject class]]

    • 左边返回一个类对象,右边遍历基类,而基类的superclass 是指向类对象的.所以返回1.

    [[NSObject class]isMemberOfClass:[NSObject class]]);
    [[student class]isKindOfClass:[student class]])
    [student class]isMemberOfClass:[student class]])

    • 类对象 != 基类

    相关文章

      网友评论

          本文标题:Super

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