iOS底层学习-day-14

前言-OC-runtime篇

我是一名iOS开发者, iOS底层 菜鸟的进阶之路30天。

问题

讲一下 OC 的消息机制

  • OC中的方法调用其实都是转成了objc_msgSend函数的调用,给receiver(方法调用者)发送了一条消息(selector方法名)
  • objc_msgSend底层有3大阶段
  • 消息发送(当前类、父类中查找)、动态方法解析、消息转发

[self class], [self superclass], [super class], [super superclass]

- (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 因为还是去找NSObject类,所以,还是找到了传进去还是当前类,self还是receiver消息接受者,那还是object_getClass(self);
        NSLog(@"[super superclass] = %@", [super superclass]); // MJPerson
    }
    return self;
}
  • classsuperclass
- (Class)class {//class底层实现,self还是receiver消息接受者
    return object_getClass(self);
}

- (Class)superclass {//superclass底层实现,self还是receiver消息接受者
    return class_getSuperclass(object_getClass(self));
}

消息转发

- (id)forwardingTargetForSelector:(SEL)aSelector {
    if (aSelector == @selector(test)) {
        // objc_msgSend([[MJCat alloc] init], aSelector)
        return [[MJCat alloc] init];
    }
    return [super forwardingTargetForSelector:aSelector];
}

//如果消息转发为空
- (id)forwardingTargetForSelector:(SEL)aSelector {
    if (aSelector == @selector(test)) {
        return nil;
    }
    return [super forwardingTargetForSelector:aSelector];
}

// 方法签名:返回值类型、参数类型
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector {
    if (aSelector == @selector(test)) {
        return [NSMethodSignature signatureWithObjCTypes:"v16@0:8"];
    }
    return [super methodSignatureForSelector:aSelector];
}

// NSInvocation封装了一个方法调用,包括:方法调用者、方法名、方法参数
//    anInvocation.target 方法调用者
//    anInvocation.selector 方法名
//    [anInvocation getArgument:NULL atIndex:0]
- (void)forwardInvocation:(NSInvocation *)anInvocation {
//    anInvocation.target = [[MJCat alloc] init];
//    [anInvocation invoke];

    [anInvocation invokeWithTarget:[[MJCat alloc] init]];
}

在这里插入图片描述

@synthesize 和 @dynamic

  • @synthesize
//现在不用写,因为编译器会自动生成_age
@synthesize age = _age, height = _height;
  • @dynamic
// 提醒编译器不要自动生成setter和getter的实现、不要自动生成成员变量
@dynamic age;
发布了31 篇原创文章 · 获赞 0 · 访问量 954

猜你喜欢

转载自blog.csdn.net/weixin_41732253/article/details/103957427
今日推荐