博客> Runtime - 运行时
Runtime - 运行时
2019-12-08 17:45 评论:0 阅读:1122 SL勿忘
ios Runloop

简介

运行时时一种面向对象的编程语言的运行环境,类似于 Java 的虚拟机
OC 最主要的特点就是在程序运行时, 以发送消息的方式调用方法
运行时是 OC 的核心,Objective-C 就是基础运行时的

利用 clang 生成中间代码

进入终端
输入以下命令:
$ clang -rewrite-objc main.m
可以将 OC 的代码重写成 C++ 的代码

运行时在开发中的最要应用场景

字典转模型
给分类增加关联对象,开发框架时解耦
交换方法,在无法修改系统或者第三方框架的方式时

    利用交换方法,先执行自己的方法
    再执行系统或第三方框架的方法
    黑魔法,对系统/框架版本有很强的依赖性

交换方法演练

导入头文件并且从 AFN 的 AFURLSessionManager.m 中复制两个静态函数

#import <objc>

static inline void af_swizzleSelector(Class theClass, SEL originalSelector, SEL swizzledSelector) {
    // 获取对象的原始方法
    Method originalMethod = class_getInstanceMethod(theClass, originalSelector);
    // 获取对象的要交换的方法 - 必须先添加方法
    Method swizzledMethod = class_getInstanceMethod(theClass, swizzledSelector);
    // 交换方法
    method_exchangeImplementations(originalMethod, swizzledMethod);
}

static inline BOOL af_addMethod(Class theClass, SEL selector, Method method) {
    // 添加方法
    return class_addMethod(theClass, selector,  method_getImplementation(method),          method_getTypeEncoding(method));
}

新建 UIImageView+Hack 分类,实现以下代码

#import "UIImageView+Hack.h"
#import <objc>

@implementation UIImageView (Hack)

+ (void)load {

    Method swizzledMethod = class_getInstanceMethod([UIImageView class], @selector(cz_setImage:));
    Method originalMethod = class_getInstanceMethod([UIImageView class], @selector(setImage:));

    // 交叉方法
    method_exchangeImplementations(swizzledMethod, originalMethod);
}

/// 设置图像
///
/// @param image UIImage
- (void)cz_setImage:(UIImage *)image {

    CGSize size = self.bounds.size;
    UIGraphicsBeginImageContextWithOptions(size, YES, 0);

    [image drawInRect:self.bounds];

    UIImage *result = UIGraphicsGetImageFromCurrentImageContext();

    UIGraphicsEndImageContext();

    // 调用系统默认方法
    [self cz_setImage:result];
}

@end

运行测试,使用模拟器的 Debug - Color Misaligned Images 测试

收藏
0
sina weixin mail 回到顶部