MST

星途 面试题库

面试题:Objective-C元类与类定义声明的深度理解

阐述Objective-C中类对象、元类对象的概念以及它们与类定义和声明的关系。当向一个类发送类方法消息时,底层的消息传递机制是怎样的,结合类的定义和声明原理详细说明。如果在运行时动态修改类的定义(例如添加新的实例方法),应该如何操作并解释其对类的结构和现有对象的影响。
14.0万 热度难度
编程语言Objective-C

知识考点

AI 面试

面试题答案

一键面试

类对象、元类对象概念及与类定义和声明的关系

  1. 类对象
    • 概念:在Objective - C中,每个类在运行时都是一个Class类型的对象,称为类对象。它包含了类的相关信息,如类名、超类、实例变量布局、方法列表等。类对象用于创建该类的实例(即对象)。
    • 与类定义和声明关系:类的声明(@interface)和定义(@implementation)定义了类的结构和行为。编译器根据这些声明和定义,在运行时创建对应的类对象。例如,当我们声明一个Person类:
@interface Person : NSObject
@property (nonatomic, copy) NSString *name;
- (void)sayHello;
@end

@implementation Person
- (void)sayHello {
    NSLog(@"Hello, my name is %@", self.name);
}
@end

运行时就会创建一个代表Person类的类对象,它包含了name属性和sayHello方法等相关信息。 2. 元类对象

  • 概念:元类对象是存储类方法的地方。每个类都有一个对应的元类对象。元类对象也是Class类型,它的超类是其类对象的超类的元类对象(根类的元类对象的超类是根类的类对象)。
  • 与类定义和声明关系:类方法在类的声明和定义中定义,例如:
@interface Person : NSObject
+ (instancetype)personWithName:(NSString *)name;
@end

@implementation Person
+ (instancetype)personWithName:(NSString *)name {
    Person *p = [[self alloc] init];
    p.name = name;
    return p;
}
@end

这些类方法存储在Person类对应的元类对象中。

向类发送类方法消息时的底层消息传递机制

  1. 当向一个类发送类方法消息时,首先会在该类对应的元类对象的方法列表中查找方法的实现。例如,对于[Person personWithName:@"John"],系统会到Person类的元类对象的方法列表中找personWithName:方法。
  2. 如果在元类对象的方法列表中没有找到,就会沿着元类对象的继承体系向上查找,即查找元类对象的超类(通常是其超类的元类对象)的方法列表,直到找到方法实现或者到达根类的元类对象且仍未找到(此时会走消息转发流程)。

运行时动态修改类的定义(添加新的实例方法)及影响

  1. 操作方法:可以使用Objective - C运行时库(<objc/runtime.h>)来动态添加实例方法。例如,假设有一个已经定义的Person类,要动态添加一个新的实例方法run
#import <objc/runtime.h>

// 定义新方法的实现
void runMethod(id self, SEL _cmd) {
    NSLog(@"%@ is running", self);
}

// 在运行时添加新方法
BOOL addMethod() {
    Class personClass = object_getClass([Person class]);
    return class_addMethod(personClass, @selector(run), (IMP)runMethod, "v@:");
}
  1. 对类结构的影响:运行时动态添加实例方法会修改类对象的方法列表,在类对象的方法列表中增加新的方法记录。
  2. 对现有对象的影响:现有对象可以立即调用新添加的方法,因为对象在接收消息时是根据类对象的方法列表来查找方法实现的。一旦类对象的方法列表更新,所有该类及其子类的对象都可以响应新添加的方法。