OC-runtime使用场景

在实际开发中,Objective-C 的运行时(runtime)是一个强大的特性,它允许开发者在程序运行时动态地操作类、对象、方法等,以下是一些常见的使用场景:

  1. 关联对象 :

    有时需要为类添加额外的属性,但又不想修改类的声明。通过 runtime 可以为类的实例动态地关联额外的数据。例如,在一个第三方库提供的类中,我们想为它添加一个自定义的标识属性,就可以使用关联对象来实现。

    objc

    less 复制代码
    #import <objc/runtime.h>
    
    @interface UIButton (CustomProperty)
    @property (nonatomic, copy) NSString *customIdentifier;
    @end
    
    @implementation UIButton (CustomProperty)
    - (void)setCustomIdentifier:(NSString *)customIdentifier {
        objc_setAssociatedObject(self, @selector(customIdentifier), customIdentifier, OBJC_ASSOCIATION_COPY_NONATOMIC);
    }
    
    - (NSString *)customIdentifier {
        return objc_getAssociatedObject(self, @selector(customIdentifier));
    }
    @end
  2. 方法交换 :

    这是一种非常有用的技术,用于在不修改原有方法实现的基础上,对方法的行为进行修改或扩展。比如在应用中,我们想统计某个方法的调用次数或在方法调用前后添加一些日志记录。

    objc

    less 复制代码
    Method originalMethod = class_getInstanceMethod([UIViewController class], @selector(viewDidLoad));
    Method swappedMethod = class_getInstanceMethod([UIViewController class], @selector(myViewDidLoad));
    method_exchangeImplementations(originalMethod, swappedMethod);
    
    - (void)myViewDidLoad {
        NSLog(@"ViewDidLoad method start");
        [self myViewDidLoad];
        NSLog(@"ViewDidLoad method end");
    }
  3. 动态创建类和对象 :

    在运行时可以动态地创建类,然后实例化对象。这在一些框架或插件系统中很有用,比如根据配置文件中的类名动态地创建类实例。

    objc

    less 复制代码
    Class newClass = objc_allocateClassPair([NSObject class], "MyDynamicClass", 0);
    // 添加属性和方法
    class_addProperty(newClass, "dynamicProperty", propertyAttributes);
    class_addMethod(newClass, @selector(dynamicMethod), (IMP)dynamicMethodImplementation, methodTypes);
    objc_registerClassPair(newClass);
    
    id instance = [[newClass alloc] init];
  4. 获取类的信息 :

    可以使用 runtime 获取类的属性列表、方法列表、协议列表等信息。这在实现一些自动序列化、反射机制或代码生成工具时非常有用。

    objc

    ini 复制代码
    unsigned int propertyCount;
    objc_property_t *properties = class_copyPropertyList([MyClass class], &propertyCount);
    for (unsigned int i = 0; i < propertyCount; i++) {
        const char *propertyName = property_getName(properties[i]);
        NSLog(@"Property: %s", propertyName);
    }
    free(properties);
  5. 消息转发机制 :

    当一个对象接收到无法响应的消息时,runtime 会启动消息转发流程。通过重写相关的消息转发方法,可以实现更灵活的消息处理。比如在一个代理模式中,当代理对象无法处理某个消息时,可以将消息转发给其他对象处理。

    objc

    python 复制代码
    - (id)forwardingTargetForSelector:(SEL)aSelector {
        if ([self.anotherObject respondsToSelector:aSelector]) {
            return self.anotherObject;
        }
        return [super forwardingTargetForSelector:aSelector];
    }

这些只是 runtime 在实际开发中的一部分应用,它为开发者提供了高度的灵活性和扩展性,能够实现很多强大的功能。

相关推荐
悠仁さん2 分钟前
【C++】set map 使用
java·前端·c++
用户093671755415 分钟前
用 4500 行 TypeScript 复刻了童年方格纸上的海战棋
前端·vue.js
CCIE-Yasuo8 分钟前
网络安全-学习web开发-基础概念、常用标签
前端·学习
凉介川14 分钟前
给 DeepSeek Harness 写插件:按扩展名接管 Windows 右键打开
前端
涛涛ing14 分钟前
Pretext之后,2026年的前端正在被“平台”和“AI”同时重写
前端
Csvn1 小时前
Worker 与 OffscreenCanvas
前端
Csvn1 小时前
图片字体
前端
m0_738120721 小时前
JWT 安全从入门到实战:六种典型攻击场景解析
前端·网络·python·安全·网络安全
拖孩1 小时前
AI 帮我写的小程序上线 44 天:36 个人进了收银台,8 个人付钱
前端·后端·微信小程序
java1234_小锋1 小时前
【技术专题】CSS3 网页技术 - CSS3 视觉增强
前端·css·css3