美文网首页Objective-C running
Objective-C Runtime 运行时初探

Objective-C Runtime 运行时初探

作者: jeckHao | 来源:发表于2017-02-21 16:00 被阅读10次

    认识

    • 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解析器

    相关文章

      网友评论

        本文标题:Objective-C Runtime 运行时初探

        本文链接:https://www.haomeiwen.com/subject/wojuwttx.html