OC runtime相关问题

161 阅读22分钟

为什么要设计metaclass

为什么要设计metaclass?

在Objective-C中,metaclass是一种特殊的类,用于存储其他类的类方法。它是Objective-C语言的一个重要特性,用于支持面向对象编程和运行时动态特性。下面是关于为什么要设计metaclass的一些原因:

  1. 支持类方法:

    • 类方法是属于类本身的方法,而不是类的实例。通过metaclass,我们可以将类方法与特定的类关联起来,使得我们可以在不创建类的实例的情况下调用这些方法。
    • 通过metaclass,我们可以在运行时动态地添加、修改或删除类方法,从而实现动态的类行为。
  2. 实现继承和多态:

    • metaclass的继承关系与类的继承关系相似。每个类都有一个对应的metaclass,而metaclass也可以有自己的超类metaclass。
    • 这种继承关系使得类方法可以被继承和重写,从而实现了多态性。子类可以重写父类的类方法,从而改变其行为。
  3. 运行时特性:

    • Objective-C是一种动态语言,它允许在运行时动态地创建、修改和调用类和对象。metaclass的存在使得我们可以在运行时动态地操作类和类方法。
    • 通过metaclass,我们可以实现一些高级的运行时特性,如方法交换、动态方法解析和消息转发等。
  4. 支持Category:

    • Category是Objective-C中的一种特性,它允许我们在不修改原始类的情况下为类添加新的方法。
    • 通过metaclass,Objective-C可以在运行时将Category中定义的方法添加到类的方法列表中,从而实现了Category的功能。

总结: metaclass在Objective-C中的设计是为了支持类方法、继承和多态、运行时特性以及Category等功能。它是Objective-C语言的一个重要组成部分,使得Objective-C具有了动态性和灵活性。


Learn more:

  1. What is a meta-class in Objective-C?
  2. iOS / Objective-C Meta Class and Category - Stack Overflow
  3. Metaclass - Wikipedia

介绍下runtime的内存模型(isa、对象、类、metaclass、结构体的存储信息等)

Objective-C的Runtime是Objective-C语言的运行时系统,它负责管理对象的创建、销毁、消息发送等底层操作。在Objective-C的Runtime中,有一些重要的概念和内存模型,包括isa指针、对象、类、元类等。

  1. isa指针:

    • 每个Objective-C对象都有一个isa指针,指向该对象所属的类。
    • isa指针的类型是一个指向objc_class结构体的指针。
    • isa指针的作用是在运行时确定对象的类,并且通过isa指针可以进行消息的动态分发。
  2. 对象:

    • Objective-C中的对象是存储在内存中的一块区域,用来存储实例变量和其他数据。
    • 对象的内存布局包括实例变量和isa指针。
    • 对象的实例变量存储在isa指针之后的内存区域。
  3. 类:

    • 类是对象的模板,用来描述对象的属性和行为。
    • 类也是一个对象,它的类是元类。
    • 类的内存布局包括父类指针、实例变量、方法列表等。
    • 类对象存储在内存中,可以通过类对象获取类的信息,如类名、父类、实例变量、方法等。
  4. 元类:

    • 元类是类对象的类,用来描述类对象的属性和行为。
    • 元类的isa指针指向基类的元类。
    • 元类的内存布局和类对象类似,包括父类指针、实例变量、方法列表等。
  5. 结构体的存储信息:

    • objc_class结构体定义了类的信息,包括isa指针、父类指针、类名、实例变量、方法列表等。
    • objc_class结构体的实例变量存储了类的实例变量的信息,包括变量名、类型、偏移量等。
    • objc_method_list结构体存储了方法列表的信息,包括方法名、方法实现等。

综上所述,Objective-C的Runtime内存模型包括对象、类、元类等概念,通过isa指针进行对象和类的关联,通过结构体存储对象和类的信息。


Learn more:

  1. Objective-C memory Layout
  2. A Modern Objective-C Runtime
  3. A brief analysis of Objective-c Runtime class and Object tutorial

class_copyIvarList & class_copyPropertyList区别

class_copyIvarList and class_copyPropertyList are both functions in Objective-C that allow you to retrieve information about the instance variables (ivars) and properties of a class, respectively. While they serve similar purposes, there are some key differences between them.

  1. Retrieved Information:

    • class_copyIvarList: This function returns an array of objc_ivar structures, which contain information about the ivars of a class. Each objc_ivar structure includes details such as the ivar's name, type encoding, and memory offset.
    • class_copyPropertyList: This function returns an array of objc_property_t structures, which contain information about the properties of a class. Each objc_property_t structure includes details such as the property's name, attributes, and type encoding.
  2. Visibility:

    • class_copyIvarList: This function retrieves all the ivars of a class, including both public and private ivars.
    • class_copyPropertyList: This function retrieves only the declared properties of a class, which are typically the publicly accessible properties.
  3. Inheritance:

    • class_copyIvarList: When called on a specific class, this function retrieves only the ivars declared in that class.
    • class_copyPropertyList: When called on a specific class, this function retrieves only the properties declared in that class. However, if you want to retrieve properties from all the superclasses as well, you need to iterate through the class hierarchy manually.

It's important to note that both class_copyIvarList and class_copyPropertyList return arrays that need to be freed using the free() function to avoid memory leaks.


Learn more:

  1. ios - class_copyPropertyList for all subclasses also - Stack Overflow
  2. Dynamic Tips & Tricks With Objective-C - Pilky.me
  3. Calling object_getClass on Swift objects - Using Swift - Swift Forums

category & extension区别,能给NSObject添加Extension吗,结果如何

In Objective-C, both categories and extensions allow you to add methods to an existing class. However, there are some differences between the two.

Categories:

  • A category allows you to add methods to an existing class, even if you don't have access to the source code of that class [1].
  • You can use a category to extend the functionality of existing classes without subclassing them [1].
  • Categories can only add methods to a class and cannot declare additional instance variables [1].
  • The methods added by a category become part of the class type and are inherited by all subclasses of that class [1].

Extensions:

  • Class extensions are similar to anonymous categories, but the methods they declare must be implemented in the main @implementation block for the corresponding class [1].
  • Extensions can also declare properties and instance variables [1].
  • Extensions are typically used to declare additional required methods for a class in locations other than within the primary class @interface block [1].
  • Unlike categories, extensions do not have a separate name in parentheses [1].

Now, regarding adding an extension to NSObject, it is possible to add an extension to NSObject. However, since NSObject is the root class for all Objective-C objects, adding an extension to NSObject will affect all objects in your application [2]. This means that any methods or properties declared in the extension will be available to all objects, including instances of subclasses of NSObject.


Learn more:

  1. objective c - Difference between Category and Class Extension? - Stack Overflow
  2. Customizing Existing Classes
  3. Categories and Extensions

消息转发机制,消息转发机制和其他语言的消息机制优劣对比

消息转发机制是Objective-C中的一种核心概念,它与传统的方法调用有着明显的区别。了解清楚消息转发机制可以极大地提高编码效率。下面将探讨其细节和实际应用,并与其他语言的消息机制进行比较。

Objective-C中的消息转发机制

在Objective-C中,消息传递是对象之间进行通信的一种方式。与直接调用方法不同,你向一个对象“传递消息”,请求它执行某个动作。这种编程范式将过程分散,为更动态的编程铺平了道路。

  • 简单的消息传递
Person *person = [[Person alloc] init];
[person sayHello];

在上面的例子中,我们创建了一个Person对象,并向其传递了一个sayHello的消息。

  • 带参数的消息传递
Person *person = [[Person alloc] init];
[person sayHelloTo:@"John"];

在这个例子中,我们向Person对象传递了一个带有参数的sayHelloTo消息。

  • 链式消息传递
Person *person = [[Person alloc] init];
person.sayHello().sayGoodbye();

在这个例子中,我们通过链式消息传递的方式,依次向Person对象传递了sayHello和sayGoodbye消息。

  • 条件消息传递
Person *person = [[Person alloc] init];
if ([person respondsToSelector:@selector(sayHello)]) {
    [person sayHello];
} else {
    NSLog(@"Person does not respond to sayHello");
}

在这个例子中,我们通过判断Person对象是否响应sayHello消息来进行条件消息传递。

Objective-C消息转发机制与其他语言的比较

Objective-C的消息转发机制与其他语言的消息机制有以下优劣对比:

优势:

  • 动态性:Objective-C的消息转发机制允许在运行时动态地决定消息的接收者和处理方式,使得代码更加灵活和动态。
  • 扩展性:通过消息转发机制,可以轻松地为现有的类添加新的方法,而无需修改原始类的代码。
  • 解耦合:消息转发机制将消息的发送者和接收者解耦,使得对象之间的通信更加灵活和可扩展。

劣势:

  • 运行时开销:由于消息转发机制需要在运行时进行动态查找和处理,因此会带来一定的运行时开销。
  • 编译时检查的缺失:由于消息转发机制的动态性,编译器无法在编译时对消息的正确性进行检查,可能会导致一些潜在的错误。

实际应用和示例

Objective-C的消息转发机制在以下情况下特别有用:

  • 在运行时动态地添加方法或修改方法的实现。
  • 实现代理模式,将消息转发给代理对象进行处理。
  • 实现消息转发链,将消息依次传递给多个对象进行处理。

最佳实践和技巧

在使用Objective-C的消息转发机制时,以下是一些最佳实践和技巧:

  • 确保正确地实现forwardInvocation:方法和methodSignatureForSelector:方法。
  • 使用respondsToSelector:方法来检查对象是否响应某个消息。
  • 谨慎使用消息转发机制,避免过度使用,以免增加代码的复杂性和运行时开销。

常见问题

以下是一些关于Objective-C消息转发机制的常见问题:

  • 什么时候会触发消息转发机制?
  • 如何实现消息转发机制?
  • 消息转发机制是否支持多重继承?

Learn more:

  1. Objects, Classes, and Messaging
  2. Objective C: Message Passing
  3. mikeash.com: Friday Q&A 2009-03-27: Objective-C Message Forwarding

什么时候会触发消息转发机制?

在Objective-C中,消息转发机制会在以下情况下被触发:

  1. 当一个对象收到一个无法响应的消息时,即该对象没有实现对应的方法时,消息转发机制会被触发[2]

消息转发机制的触发过程如下:

  1. 懒加载方法解析(Lazy method resolution):运行时会发送resolveInstanceMethod:消息给该对象所属的类,如果该方法返回YES,表示该类已经动态添加了对应的方法,然后重新开始消息发送过程[3]

  2. 快速转发路径(Fast forwarding path):运行时会发送forwardingTargetForSelector:消息给该对象,如果该方法被实现并且返回值不为nil或self,那么整个消息发送过程会重新开始,但以返回值作为新的消息接收者[3]

  3. 正常转发路径(Normal forwarding path):首先,运行时会发送methodSignatureForSelector:消息给该对象,以获取消息的参数和返回值类型。如果能够获取到方法签名,运行时会创建一个NSInvocation对象来描述该消息,并发送forwardInvocation:消息给该对象。如果无法获取到方法签名,运行时会发送doesNotRecognizeSelector:消息给该对象,表示无法识别该消息[3]


Learn more:

  1. Message Forwarding in Objective C - Stack Overflow
  2. One More Thing: Message Forwarding | Objective-C Boot Camp | InformIT
  3. mikeash.com: Friday Q&A 2009-03-27: Objective-C Message Forwarding

如何实现消息转发机制?

Objective-C中实现消息转发机制需要重写两个方法:methodSignatureForSelector:forwardInvocation:

  1. methodSignatureForSelector:方法用于创建另一个类实现的消息的有效方法签名。在这个方法中,你可以检查其他对象是否实现了该消息,如果实现了,可以返回一个有效的方法签名。这个方法的实现可以参考以下示例代码:
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector {
    NSMethodSignature *methodSignature = [super methodSignatureForSelector:aSelector];
    if (!methodSignature) {
        // Check if another object responds to the selector
        if ([otherObject respondsToSelector:aSelector]) {
            methodSignature = [otherObject methodSignatureForSelector:aSelector];
        }
    }
    return methodSignature;
}
  1. forwardInvocation:方法用于将选择器转发给实际实现该消息的对象。在这个方法中,你可以检查其他对象是否响应该选择器,并在满足条件时将选择器转发给其他对象。这个方法的实现可以参考以下示例代码:
- (void)forwardInvocation:(NSInvocation *)anInvocation {
    // Check if another object responds to the selector
    if ([otherObject respondsToSelector:[anInvocation selector]]) {
        [anInvocation invokeWithTarget:otherObject];
    } else {
        // Handle the case when no object can respond to the selector
        [super forwardInvocation:anInvocation];
    }
}

这样,当一个对象收到一个无法响应的消息时,就会触发消息转发机制,你可以在这两个方法中实现自定义的逻辑来处理这些消息。


Learn more:

  1. One More Thing: Message Forwarding | Objective-C Boot Camp
  2. Message Forwarding in Objective C - Stack Overflow
  3. mikeash.com: Friday Q&A 2009-03-27: Objective-C Message Forwarding

消息转发机制是否支持多重继承?

Objective-C does not support multiple inheritance. However, you can achieve similar functionality using a combination of protocols, composition, and message forwarding [1].

Here's how you can approach it:

  1. Protocols: In Objective-C, protocols define a set of methods that an object must implement. You can create protocols to define the required functionality of different classes.

  2. Composition: Composition is the technique of including a reference to another object and calling that object when its functionality is required. You can create a class that includes references to multiple objects of different classes.

  3. Message Forwarding: Message forwarding is a mechanism that allows objects to pass messages onto other objects. In Objective-C, you can implement the forwardInvocation: method to handle method invocations that the current object cannot handle itself. Inside this method, you can check if the referenced objects respond to the invoked method and forward the message to the appropriate object.

Here's an example code snippet:

@interface ClassA : NSObject
- (void)methodA;
@end

@interface ClassB : NSObject
- (void)methodB;
@end

@interface MyClass : NSObject
@property (nonatomic, strong) ClassA *a;
@property (nonatomic, strong) ClassB *b;
@end

@implementation MyClass

- (void)forwardInvocation:(NSInvocation *)anInvocation {
    if ([self.a respondsToSelector:[anInvocation selector]]) {
        [anInvocation invokeWithTarget:self.a];
    } else if ([self.b respondsToSelector:[anInvocation selector]]) {
        [anInvocation invokeWithTarget:self.b];
    } else {
        [super forwardInvocation:anInvocation];
    }
}

@end

In this example, MyClass includes references to objects of ClassA and ClassB. When a method is invoked on MyClass, the forwardInvocation: method is called. Inside this method, it checks if ClassA or ClassB can respond to the invoked method and forwards the message accordingly.

Please note that this approach assumes that ClassA and ClassB do not have any common methods. If they do, you may need to handle the method resolution more carefully.


Learn more:

  1. interface - Multi inheritance for IOS - Stack Overflow
  2. Is Multiple Inheritance Allowed in Programming Languges? | by Beyza Gizem Yıldırım | Medium
  3. struct embedding is multiple inheritance? - understanding golang

实现消息转发链,将消息依次传递给多个对象进行处理

在Objective-C中,可以通过消息转发机制实现将消息依次传递给多个对象进行处理。下面是一种实现消息转发链的方法:

  1. 创建一个中间对象,该对象将作为消息转发链的起点。
  2. 在中间对象中定义一个方法,用于接收消息并将其传递给下一个对象。
  3. 在中间对象中定义一个属性,用于保存下一个对象的引用。
  4. 在中间对象的方法中,将接收到的消息转发给下一个对象进行处理。
  5. 在下一个对象中,重复步骤2-4,将消息继续传递给下一个对象,直到所有对象都处理完消息或消息无法处理为止。

下面是一个示例代码,演示了如何实现消息转发链:

// 中间对象
@interface MessageForwardingChain : NSObject

@property (nonatomic, strong) id nextObject;

- (void)forwardMessage:(SEL)selector;

@end

@implementation MessageForwardingChain

- (void)forwardMessage:(SEL)selector {
    if ([self.nextObject respondsToSelector:selector]) {
        [self.nextObject performSelector:selector];
    } else {
        NSLog(@"Message cannot be handled by any object in the chain.");
    }
}

@end

// 对象A
@interface ObjectA : NSObject

- (void)handleMessage;

@end

@implementation ObjectA

- (void)handleMessage {
    NSLog(@"Object A handles the message.");
}

@end

// 对象B
@interface ObjectB : NSObject

- (void)handleMessage;

@end

@implementation ObjectB

- (void)handleMessage {
    NSLog(@"Object B handles the message.");
}

@end

// 对象C
@interface ObjectC : NSObject

- (void)handleMessage;

@end

@implementation ObjectC

- (void)handleMessage {
    NSLog(@"Object C handles the message.");
}

@end

// 在使用中间对象构建消息转发链
MessageForwardingChain *chain = [[MessageForwardingChain alloc] init];

ObjectA *objectA = [[ObjectA alloc] init];
ObjectB *objectB = [[ObjectB alloc] init];
ObjectC *objectC = [[ObjectC alloc] init];

chain.nextObject = objectA;
objectA.nextObject = objectB;
objectB.nextObject = objectC;

// 发送消息
SEL selector = @selector(handleMessage);
[chain forwardMessage:selector];

运行上述代码,将会依次输出以下内容:

Object A handles the message.
Object B handles the message.
Object C handles the message.

这样,消息就会依次传递给多个对象进行处理。


Learn more:

  1. 为什么Objective-C的消息转发要设计三个阶段? - 掘金
  2. 【iOS】-- 消息传递与转发 - 掘金
  3. 用代码理解 ObjC 中的发送消息和消息转发 - LPD-iOS

在方法调用的时候,方法查询-> 动态解析-> 消息转发 之前做了什么

在iOS中,方法调用的过程可以分为三个阶段:方法查询、动态解析和消息转发。在这三个阶段之前,还有一些准备工作需要完成。

  1. 类加载和方法注册:在程序启动时,iOS会加载所有的类,并将每个类的方法注册到运行时系统中。这样,在方法调用时,系统就能够知道每个类中的方法列表。

  2. 方法查询:当一个对象调用方法时,首先会在该对象所属的类的方法列表中查找对应的方法。如果找到了匹配的方法,就直接执行该方法。如果没有找到匹配的方法,则进入下一阶段。

  3. 动态解析:在动态解析阶段,系统会尝试动态地为找不到的方法添加实现。这个过程分为两个步骤:

    a. 动态方法解析:系统会调用类方法+ (BOOL)resolveInstanceMethod:(SEL)sel+ (BOOL)resolveClassMethod:(SEL)sel,给类一个机会来动态添加方法的实现。如果类成功添加了方法的实现,那么方法查询阶段会重新开始,重新查找并执行该方法。

    b. 备用的接收者:如果动态方法解析没有成功添加方法的实现,系统会调用实例方法- (id)forwardingTargetForSelector:(SEL)aSelector,给对象一个机会将方法转发给其他对象来处理。如果对象返回了一个备用的接收者,系统会将方法调用转发给该对象,并执行对应的方法。

  4. 消息转发:如果以上两个阶段都没有成功找到方法的实现,系统会进入消息转发阶段。在消息转发阶段,系统会将消息封装成一个NSInvocation对象,并调用实例方法- (void)forwardInvocation:(NSInvocation *)anInvocation。在该方法中,开发者可以自定义处理未知方法的逻辑,比如将消息转发给其他对象来处理,或者修改消息内容后再执行。

  5. 异常处理:如果以上三个阶段都没有成功找到方法的实现,系统会调用- (void)doesNotRecognizeSelector:(SEL)aSelector方法,抛出一个异常,表示找不到对应的方法。


Learn more:

  1. -- iOS 运行时中方法的调用流程 - 简书
  2. iOS 消息调用的过程 - 掘金
  3. iOS底层原理之方法调用的底层探究 - 掘金

IMP、SEL、Method的区别和使用场景

在Runtime中,SEL、Method和IMP是Objective-C中用于处理方法调用和消息传递的重要概念。它们之间有一些区别和使用场景。

  1. SEL(选择子):

    • 定义:SEL是一个指向objc_selector结构体的指针,代表方法的名称。它仅以名字来识别方法[1]
    • 使用场景:SEL用于在运行时标识方法。可以通过@selector()语法获取方法的SEL,并用于消息传递和方法调用[1]
  2. IMP(方法实现):

    • 定义:IMP是一个函数指针,指向方法的实现代码。它使用标准的C调用方式,接受一个id类型的参数作为消息的接收者,一个SEL类型的参数表示方法的选择子,以及可选的其他参数[1]
    • 使用场景:IMP用于直接调用方法的实现代码。可以通过获取方法的IMP,绕过消息传递的过程,直接调用方法的实现代码[1]
  3. Method(方法):

    • 定义:Method是一个指向objc_method结构体的指针,它包含了一个SEL和一个IMP,相当于在SEL和IMP之间建立了一个映射关系[1]
    • 使用场景:Method对开发者来说是一种不透明的类型,一般不直接使用。它被隐藏在我们书写的类或对象的方法背后,用于在运行时查找方法的SEL和IMP[1]

综上所述,SEL用于标识方法的名称,IMP用于直接调用方法的实现代码,而Method则是SEL和IMP之间的映射关系。它们在Runtime中的使用场景如下:

  • 使用SEL可以在运行时标识方法,用于消息传递和方法调用。
  • 使用IMP可以直接调用方法的实现代码,绕过消息传递的过程。
  • Method一般不直接使用,它被隐藏在类或对象的方法背后,用于在运行时查找方法的SEL和IMP。

Learn more:

  1. iOS面试题:Runtime中,SEL、Method 和 IMP有什么区别,使用场景? - 简书
  2. iOS面试题:Runtime中,SEL、Method 和 IMP有什么区别,使用场景?_method 和sel-CSDN博客
  3. iOS面试题:Runtime中,SEL、Method 和 IMP有什么区别,使用场景? - 知乎

说说消息转发机制的优劣

Objective-C的消息转发机制是一种用于在运行时动态处理未知消息的机制。它具有一些优点和劣势,下面我将详细介绍它们。

优点:

  1. 灵活性:消息转发机制允许在运行时动态处理未知消息,这使得我们可以在不修改源代码的情况下,为对象添加新的方法或重写现有方法的实现[1]
  2. 可扩展性:通过消息转发机制,我们可以在运行时将消息转发给其他对象来处理,这使得系统的节点数量增加时,可以方便地扩展消息的处理[2]
  3. 可靠性:通过设置重试机制,消息转发机制可以保证消息不会丢失,从而提高系统的可靠性[2]

劣势:

  1. 性能问题:由于消息转发需要经过多次传递,这可能导致性能问题。每次消息转发都需要在对象的方法列表中查找对应的方法实现,这会带来一定的开销[2]
  2. 复杂度问题:实现消息转发机制需要考虑很多因素,包括动态方法解析、备援接收者和消息转发等步骤,这增加了代码的复杂度和维护成本[2]

综上所述,Objective-C的消息转发机制在灵活性和可扩展性方面具有优势,但在性能和复杂度方面存在一些劣势。在实际开发中,我们需要根据具体情况权衡利弊,合理使用消息转发机制。


Learn more:

  1. 聊一聊 Objective-C 的优缺点 - 简书
  2. 消息转发机制的优劣-掘金
  3. ios 消息转发机制的优劣-掘金

关联对象的应用?系统如何实现关联对象的

关联对象是一种在Objective-C中动态添加属性的技术,它允许我们在运行时为对象添加额外的属性。这在一些情况下非常有用,特别是在使用分类扩展现有类时。

关联对象的应用

关联对象的应用场景包括但不限于以下几种情况:

  1. 给系统类添加属性:通过使用关联对象技术,我们可以给系统类添加自定义属性,而无需修改系统类的源代码。这在一些情况下非常有用,例如给NSObject类添加一个name属性[1]

  2. 为分类添加属性:使用关联对象技术,我们可以给分类添加属性,从而为分类提供额外的数据存储能力。这样,我们可以在分类中添加自定义的属性,而不仅仅局限于方法的扩展[1]

  3. 在运行时动态关联对象:关联对象技术允许我们在运行时动态地为对象添加属性。这对于需要在运行时根据条件或动态生成的属性非常有用,可以灵活地根据需要添加和移除属性[1]

系统如何实现关联对象的

Objective-C中的关联对象是通过Runtime库来实现的。Runtime库提供了一组函数来操作关联对象,其中最常用的函数是objc_setAssociatedObjectobjc_getAssociatedObject

  1. objc_setAssociatedObject函数:这个函数用于给对象添加关联对象。它接受四个参数:对象、关联对象的键、关联对象的值和关联策略。关联策略定义了关联对象的内存管理方式,例如强引用、弱引用或复制[1]

  2. objc_getAssociatedObject函数:这个函数用于获取对象的关联对象。它接受两个参数:对象和关联对象的键。通过这个函数,我们可以获取到之前通过objc_setAssociatedObject函数设置的关联对象的值[1]

关联对象的实现原理涉及到几个核心对象:

  • AssociationsManager:这个对象是关联对象技术的核心管理器,它内部包含一个AssociationsHashMap对象。

  • AssociationsHashMap:这个对象是一个哈希表,用于存储对象和其关联对象之间的映射关系。它的键是一个disguised_ptr_t类型的指针,值是一个ObjectAssociationMap对象。

  • ObjectAssociationMap:这个对象是一个字典,用于存储对象的关联对象。它的键是一个objc_AssociationKey类型的指针,值是一个ObjcAssociation对象。

  • ObjcAssociation:这个对象存储了关联对象的值和关联策略。

通过以上对象的组合,Objective-C实现了关联对象的功能。具体的实现细节可以参考相关的Runtime源码。


Learn more:

  1. iOS底层原理总结 - 关联对象实现原理 - 掘金
  2. OC底层原理探究之关联对象 - 掘金
  3. AssociatedObject关联对象原理实现 | Vanch's Blog