当前位置: 首页 > article >正文

iOS - Objective-C语言的动态性

Objective-C 的动态性主要由以下几个关键特性和机制支撑:

1. 动态消息传递

// 消息传递机制
id objc_msgSend(id self, SEL _cmd, ...) {
    // 1. 获取类信息
    Class cls = object_getClass(self);
    
    // 2. 查找方法实现
    IMP imp = lookUpImpOrForward(cls, _cmd);
    
    // 3. 执行方法
    return imp(self, _cmd, ...);
}

// 动态调用
[object performSelector:@selector(methodName)];

2. 动态类型

// id 类型
id obj = [[NSObject alloc] init];

// 动态类型检查
if ([obj isKindOfClass:[NSString class]]) {
    // 运行时检查类型
}
  • id 类型:可以指向任何对象,类型信息在运行时确定。
  • 动态类型检查:使用 isKindOfClass: 和 respondsToSelector: 等方法在运行时检查类型。

3. 动态方法解析

// 动态方法解析
+ (BOOL)resolveInstanceMethod:(SEL)sel {
    if (sel == @selector(dynamicMethod)) {
        class_addMethod(self, sel, (IMP)dynamicMethodIMP, "v@:");
        return YES;
    }
    return [super resolveInstanceMethod:sel];
}
  • 方法解析:在运行时动态添加方法实现。
  • resolveInstanceMethod::允许在方法未找到时提供实现。

4. 方法交换 (Method Swizzling)

// 方法交换
Method originalMethod = class_getInstanceMethod(self, @selector(originalMethod));
Method swizzledMethod = class_getInstanceMethod(self, @selector(swizzledMethod));
method_exchangeImplementations(originalMethod, swizzledMethod);

5. 动态类和对象

// 动态创建类
Class newClass = objc_allocateClassPair([NSObject class], "NewClass", 0);
objc_registerClassPair(newClass);

// 动态添加属性
class_addIvar(newClass, "dynamicIvar", sizeof(id), log2(sizeof(id)), @encode(id));
  • 动态类创建:可以在运行时创建新类。
  • 动态属性和方法:可以在运行时添加属性和方法。

6. 关联对象

// 关联对象
objc_setAssociatedObject(obj, @selector(associatedObject), value, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
id value = objc_getAssociatedObject(obj, @selector(associatedObject));
  • 关联对象:在运行时为对象动态添加属性。

7. 反射机制

// 反射
Class cls = [obj class];
Method *methods = class_copyMethodList(cls, &methodCount);
  • 反射:在运行时获取类和对象的详细信息。

8. 运行时库

  • Objective-C Runtime Library:提供了丰富的 API 支持动态特性,如 objc_getClass、class_addMethod、method_getImplementation 等。

这些特性使得 Objective-C 能够在运行时灵活地处理对象和方法,支持动态行为和元编程。


http://www.kler.cn/a/501590.html

相关文章:

  • JVM:ZGC详解(染色指针,内存管理,算法流程,分代ZGC)
  • 《DOM NodeList》
  • 基类指针指向派生类对象,基类指针的首地址永远指向子类从基类继承的基类首地址
  • 交响曲-24-3-单细胞CNV分析及聚类
  • Objective-C语言的语法
  • XS5037C一款应用于专业安防摄像机的图像信号处理芯片,支持MIPI和 DVP 接口,内置高性能ISP处理器,支持3D降噪和数字宽动态
  • MacOS15 bash 终端怎么使用网络代理
  • 《拉依达的嵌入式\驱动面试宝典》—操作系统篇(五)
  • Kotlin 极简小抄 P5(异常、异常处理、自定义异常)
  • 三天学完微服务其二
  • 【江协STM32】10-4/5 I2C通信外设、硬件I2C读写MPU6050
  • Web3 重塑隐私保护:构建数字安全新防线
  • Flutter:吸顶效果
  • git打补丁
  • 010:传统计算机视觉之大津算法初探
  • centos7.6 安装nacos 2.0.4与恢复nacos的mysql
  • 【Ubuntu与Linux操作系统:八、Ubuntu桌面应用】
  • 因泰立科技激光车检器,高速公路的精准流量统计专家
  • ubuntu编译ijkplayer,支持rmvb以及mkv
  • 【集成学习】Bagging、Boosting、Stacking算法详解
  • HTML语言的数据库编程
  • 英语互助小程序springboot+论文源码调试讲解
  • 【Uniapp-Vue3】uniapp创建组件
  • 通过ESP32和INMP441麦克风模块实现音频数据传递
  • Scala语言的数据类型
  • #Uniapp: uniapp国际化适配