返回

iOS 分类底层原理深度剖析:从 load 方法到关联对象

IOS

引言

分类是 Objective-C 中一项强大的特性,允许我们为现有类添加方法和属性,而无需修改其源代码。然而,其底层实现机制却鲜为人知。本篇文章将深入剖析 iOS 分类底层的原理,从 load 方法的解析到 +load 和 +initialize 的区别,再到关联对象的实现机制,帮助你全面理解分类的运作原理,优化 iOS 应用开发。

load 方法的解析

load 方法是 Objective-C 中一个特殊的方法,会在类或分类加载到内存时被调用。其作用是为类或分类进行初始化操作,比如注册通知、设置默认值等。对于分类来说,load 方法会在 runtime 加载类和分类时被调用,因为所有的类和分类都会在程序启动时被载入内存,所以所有的类和分类不管有没有被用到都会触发 load 方法的调用。

+load 和 +initialize 的区别

+load 和 +initialize 都是类方法,都会在类加载时被调用,但二者之间存在着细微的区别:

  • +load: +load 方法会在类或分类第一次加载到内存时被调用,且只会被调用一次。其主要用于进行一些全局性的初始化操作,比如注册通知、设置默认值等。
  • +initialize: +initialize 方法会在类或分类的每一个实例被创建时被调用。其主要用于为实例进行初始化操作,比如分配内存、设置实例变量等。

给分类“添加成员变量”

分类虽然可以为现有类添加方法和属性,但不能直接添加成员变量。这是因为成员变量是存储在类对象中的,而分类并没有自己的类对象。为了给分类“添加成员变量”,我们可以使用关联对象。

关联对象实现原理

关联对象是一种机制,允许我们将任意数据与一个对象关联起来。其原理是通过哈希表将数据与对象关联,当我们访问关联对象时,会先根据对象计算哈希值,然后在哈希表中查找对应的值。

调用时机

load 方法会在 runtime 加载类或分类时调用。在 iOS 中,runtime 会在程序启动时加载所有的类和分类,所以所有的类和分类都会触发 load 方法的调用。

代码示例

@implementation MyClass (MyCategory)

+ (void)load {
    // 进行初始化操作
}

- (void)myMethod {
    // 使用关联对象
    objc_setAssociatedObject(self, @"key", @"value", OBJC_ASSOCIATION_RETAIN);
    NSString *value = objc_getAssociatedObject(self, @"key");
}

@end

结论

iOS 分类是一种强大的特性,其底层原理涉及 load 方法、关联对象等机制。通过理解这些原理,我们可以更有效地使用分类,优化 iOS 应用开发。在本文中,我们深入剖析了 iOS 分类底层原理,希望能够帮助你提升对 iOS 开发的理解和应用能力。