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 在实际开发中的一部分应用,它为开发者提供了高度的灵活性和扩展性,能够实现很多强大的功能。

相关推荐
鹿心肺语3 小时前
前端HTML转PDF的两种主流方案深度解析
前端·javascript
海石3 小时前
去到比北方更北的地方—2025年终总结
前端·ai编程·年终总结
一个懒人懒人3 小时前
Promise async/await与fetch的概念
前端·javascript·html
Mintopia3 小时前
Web 安全与反编译源码下的权限设计:构筑前后端一致的防护体系
前端·安全
输出输入3 小时前
前端核心技术
开发语言·前端
Mintopia4 小时前
Web 安全与反编译源码下的权限设计:构建前后端一体的信任防线
前端·安全·编译原理
林深现海4 小时前
Jetson Orin nano/nx刷机后无法打开chrome/firefox浏览器
前端·chrome·firefox
黄诂多4 小时前
APP原生与H5互调Bridge技术原理及基础使用
前端
前端市界4 小时前
用 React 手搓一个 3D 翻页书籍组件,呼吸海浪式翻页,交互体验带感!
前端·架构·github
文艺理科生4 小时前
Nginx 路径映射深度解析:从本地开发到生产交付的底层哲学
前端·后端·架构