Objective-C Runtime 运行时初探

认识

  • Objective-C语言是一门动态语言,它将很多静态语言在编译和链接时期做的事情放在了运行时来处理。
  • 这种特性意味着Objective-C不仅需要一个编译器,还需要一个运行时系统来执行编译的代码,这个运行时系统就是Objc Runtime。
  • Runtime库主要做下面两个时期:
    • 封装:在这个库中,对象可以用C语言中的结构体表示,而方法可以用C函数来实现,另外再加上一些额外的特性。这些结构体和函数被runtime函数封装后,我们就可以在程序运行时创建,检查,修改类和对象和它们的方法了。
    • 找出方法的最终执行代码:当程序执行[object doSomething]时,会向消息接受者(object)发送一条消息(dosomething),runtime会根据消息接受者是否能响应消息而做出不同的反应。

能做什么?

  • 动态创建函数、类、替换已有的函数
  • 动态创建protocol、创建子类
  • 了解runtime可以让你知道通过clang编译器,你的objective-C
    代码转成了什么样c代码

类与对象数据结构、操作函数

这里有详细的介绍类与对象的数据结构和操作函数的文章,大家可以移驾,这里边有很全的介绍,下面是我学习的时候自己撸的代码github地址

这里必须看这个文章,比我要写的全面:http://blog.jobbole.com/79566/?utm_source=blog.jobbole.com&utm_medium=relatedPosts#article-comment

具体应用1:替换数组、字典的取值函数越界问题

在做iOS的时候,因为OC是运行时语言,往往在数组中去数值或者向字典中插入数值的时候,会有nil的现象,这种时候可以通过runtime来避免。项目源码github地址

具体应用2:黑魔法(Method Swizzing)

例如,我们想跟踪在程序中每一个view controller展示给用户的次数:当然,我们可以在每个view controller的viewDidAppear中添加跟踪代码;但是这太过麻烦,需要在每个view controller中写重复的代码。创建一个子类可能是一种实现方式,但需要同时创建UIViewController, UITableViewController, UINavigationController及其它UIKit中view controller的子类,这同样会产生许多重复的代码。

#import <objc/runtime.h>
 
@implementation UIViewController (Tracking)
 
+ (void)load {
        static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        Class class = [self class];         
        // When swizzling a class method, use the following:
                    // Class class = object_getClass((id)self);
 
        SEL originalSelector = @selector(viewWillAppear:);
                    SEL swizzledSelector = @selector(xxx_viewWillAppear:);
 
        Method originalMethod = class_getInstanceMethod(class, originalSelector);
                    Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);
 
        BOOL didAddMethod =
                        class_addMethod(class,
                originalSelector,
                method_getImplementation(swizzledMethod),
                method_getTypeEncoding(swizzledMethod));
 
        if (didAddMethod) {
                        class_replaceMethod(class,
                swizzledSelector,
                method_getImplementation(originalMethod),
                method_getTypeEncoding(originalMethod));
        } else {
            method_exchangeImplementations(originalMethod, swizzledMethod);
        }
    });
}
 
#pragma mark - Method Swizzling
 
- (void)xxx_viewWillAppear:(BOOL)animated {
    [self xxx_viewWillAppear:animated];
    NSLog(@"viewWillAppear: %@", self);
}
@end

注意事项:

1:Swizzling应该总是在+load中执行
2:Swizzling应该总是在dispatch_once中执行

具体应用3:model和json解析器

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 这篇文章完全是基于南峰子老师博客的转载 这篇文章完全是基于南峰子老师博客的转载 这篇文章完全是基于南峰子老师博客的...
    西木阅读 30,591评论 33 466
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 12,198评论 4 61
  • 禅与 Objective-C 编程艺术 (Zen and the Art of the Objective-C C...
    GrayLand阅读 1,644评论 1 10
  • *面试心声:其实这些题本人都没怎么背,但是在上海 两周半 面了大约10家 收到差不多3个offer,总结起来就是把...
    Dove_iOS阅读 27,203评论 30 471
  • 昨天在藏书馆,一口气看完了小说《喜宝》 一年前,听了庆山的小说《暖暖》 《暖暖》是个哀伤而优美的故事,里面有提到亦...
    素白yan阅读 321评论 0 0