猫猫学iOS之RunTime理解运用

作者: 翟乃玉 | 来源:发表于2016-06-16 11:39 被阅读822次

    猫猫分享,必须精品

    原创文章,欢迎转载。转载请注明:翟乃玉的博客
    地址:http://www.jianshu.com/notebooks/4236923/latest

    一:RunTime简介

    Objective-C是一门动态语言,他将一些工作从编译阶段推迟到了运行阶段,比如调用方法:

    1. 在C语音当中,调用方法在编译的时候就知道具体调用哪个方法;(C语言调用 未实现的方法 就会报错)

      图1.1 只定义方法,未实现
      1.1 如图1.1 在掉用只声明而没有实现的方法,在编译的时候就直接报错了。
      图1.2
      1.2 正确的应该是图1.2
    2. 在Objective-C语音当中,调用方法是动态的,在编译的时候并不能真正决定调用哪个方法(只要有声明,既是没有实现就不会报错),只有在真正运行的时候才会根据方法的编号(名称)找到对应的方法来调用。

      2.1
      2.1 图2.1中定义了Cat类,然后声明了吃食物的方法,没有实现方法的情况下只是报了警告,但是在运行的时候就会报错:
      Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[Cat eatWithFood:]: unrecognized selector sent to instance 0x7f9b1b4da8e0'
      //定义类
      @interface Cat : NSObject
      - (void)eatWithFood:(NSString *)food;
      + (void)eatWithFood:(NSString *)food;
      @end
    
      @implementation Cat
      @end
    
     //调用
     Cat *cat = [[Cat alloc]init];
      [cat eatWithFood:@"鱼"];
    

    RunTime翻译过来就是运行时,其实就是OC的运行时机制,搜索runtime会发现很多都有运行时机制,简单说就是运行的时候的一些机制,在OC中最主要的就是消息机制

    二:RunTime的准备

    • xcode5之后,苹果不建议使用底层的方法,xcode5之后,使用运行时要做一些编译的设置,我们可以修改下,解决如下图:
      Build Settings -> 搜索msg 讲对应yes改为no(严肃的检查oc的消息机制)


    三:RunTime的运用

    定义猫类并且实现方法,后面都是根据这个类玩的。

    @interface Cat : NSObject
    - (void)eatWithFood:(NSString *)food;
    + (void)eatWithFood:(NSString *)food;
    @end
    
    @implementation Cat
    
    -(void)eatWithFood:(NSString *)food{
        NSLog(@"对象方法————  对象猫在吃%@",food);
    }
    
    +(void)eatWithFood:(NSString *)food{
        NSLog(@"类方法————  猫类在吃%@",food);
    }
    @end
    

    1、RunTime调用对象方法

    //初始化对象
        Cat *cat = [[Cat alloc]init];
        //最常用的方法调用
        [cat eatWithFood:@"鱼"];
        //perfor方法调用
        [cat performSelector:@selector(eatWithFood:) withObject:@"肉"];
        //runtime调用
        objc_msgSend(cat, @selector(eatWithFood:),@"老鼠");
    

    其实这三种方式最终都会用runtime来执行。

    2、RunTime调用类方法

    //最常用的方法调用
        [Cat eatWithFood:@"鱼"];
        //类对象
        Class catClass = [Cat class];
        //perfor方法调用
        [catClass performSelector:@selector(eatWithFood:) withObject:@"肉"];
        //runtime调用
        objc_msgSend(catClass, @selector(eatWithFood:),@"老鼠");
    

    对于类方法来说,其实其本质还是说用对象调用方法,已知,对象调用方法的本质是让对象发送消息,我们可以看出,类方法的调用其实就是底层让类对象发送消息,从而实现类方法的调用。

    • 这里其实很绕,学过java的都应该理解过一个概念,指向类的类,学过C的都知道另一个更牛逼的概念,指向指针的指针。。。总之,当年理解这些的时候猫就一个感觉:『这他喵的都是些什么鬼』

    • 其实这个也不是很难理解,类是什么?就是一类事物嘛,比如猫类是一个类,我家的猫是一个猫对象,那么同理,对于抽象『类』这一类事物的总称,我们可以称之为类类,(这东西用中文更绕)就是我们在代码中看到的 Class ,而上述代码中的catClass 就是Class 的一个对象,我们可以用catClass来代表 Cat这个类,这也就是说 catClass 是表示Cat类的类。
      ** 好吧,在说下我的理解吧,我们平时定义类的时候,一般都有方法和属性(其他的isa都不考虑), 猫有一些属性,还有方法,我们可以将之抽象成代码 Cat类,狗也有属性和方法,人也有。。。万物都有,于是我们可以将这些都有属性和方法的东东抽象成一个类,称之为类类(Class)而像猫类,狗类,人类等等都是这个类的一个对象。

    • 消息机制原理:对象根据方法编号SEL去映射表查找对应的方法实现

    图来源于网络

    相关文章

      网友评论

      本文标题:猫猫学iOS之RunTime理解运用

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