zoukankan      html  css  js  c++  java
  • 快速上手Runtime(一)之消息机制

    Runtime简介

    Runtime简称运行时。OC就是运行时机制,也就是在运行时候的一些机制,其中最主要的是消息机制。

    对于C语言,函数的调用在编译的时候会决定调用哪个函数。

    对于OC的函数,属于动态调用过程,在编译的时候并不能决定真正调用哪个函数,只有在真正运行的时候才会根据函数的名称找到对应的函数来调用。

    事实证明:
    在编译阶段,OC可以调用任何函数,即使这个函数并未实现,只要声明过就不会报错。
    在编译阶段,C语言调用未实现的函数就会报错。

    举个简单栗子:

    NSString* testObject = [[NSData alloc] init];    testObject 在编译时和运行时分别是什么类型?

    首先,声明 NSString *testObject 是告诉编译器,testObject是一个指向某个Objective-C对象的指针。因为不管指向的是什么类型的对象,一个指针所占的内存空间都是固定的,所以这里声明成任何类型的对象,最终生成的可执行代码都是没有区别的。这里限定了NSString只不过是告诉编译器,请把testObject当做一个NSString来检查,如果后面调用了非NSString的方法,会产生警告。

    接着,你创建了一个NSData对象,然后把这个对象所在的内存地址保存在testObject里。那么运行时,testObject指向的内存空间就是一个NSData对象。你可以把testObject当做一个NSData对象来用。

    回归正题:

    我们都知道一个对象的初始化可分为两步:

    1.一个对象的初始化方法分解为两步: alloc 来开辟空间,init 来初始化 :id objc = [NSObject alloc];开辟内存空间,objc = [objc init];来初始化

    2.第一步初始化过程用runtime来实现:

      id objc = [NSObject alloc];  ---> id objc = objc_msgSend([NSObject class],@selector(alloc)));

      objc = [objc init]; -------> objc = objc_msgSend(objc,@selector(init));

    下面看栗子:

    首先定义一个Person类

    #import <Foundation/Foundation.h>
    
    @interface Person : NSObject
    
    - (void)name;
    
    + (void)name;
    
    @end
    
    
    
    #import "Person.h"
    
    @implementation Person
    
    - (void)name{
        NSLog(@"对象方法---I'm doman");
    }
    
    + (void)name{
        NSLog(@"类方法---I'm doman");
    
    }
    
    @end

    通常情况下 我们都调用对象方法和类方法都是这样调的:

    #pragma mark 如果是自己测试,请先移步Build Setting -> 搜索msg -> 设置属性为No
        
        //对象方法做法1
        Person *p1 = [[Person alloc] init];
        [p1 name];
        
        //对象方法做法2
        Person *p2 = [[Person alloc] init];
        [p2 performSelector:@selector(name)];
        // SEL:方法编号,根据方法编号就可以找到对应方法实现,此方法其实就是运用了运行时。
        
        //类方法做法1
        [Person name];
        
        //类方法做法2--通过类对象调用
        [[Person class] name];
        

    其实上述方法的本质都是消息发送,那么接下来我们看用Runtime如何实现调用name方法:

    1.第一步:引入Runtime框架import <objc/message.h>,注意,使用message,不使用<objc/runtime.h>的原因是message.h涵盖runtime,方法更全。

    2.第二步:Build Setting -> 搜索msg -> 设置属性为No

    3.使用objc_msgSend,方法;注意:只有对象才能发送消息,因此以objc开头.

        // 让person发送消息-对象方法
        Person *p3 = [[Person alloc]init];
        
        objc_msgSend(p3,@selector(name));
        
        //类方法使用runtime
        // 获取类对象
        Class personClass = [Person class];
        
        objc_msgSend(personClass, @selector(name));
        
    
        

    调用结果:

     
    Demo 地址:https://github.com/domanc/Runtime_Person.git
  • 相关阅读:
    数组中的逆序对 --剑指offer
    第一个只出现一次的字符 --剑指offer
    丑数 --剑指offer
    把数组排成最小的数 --剑指offer
    整数中1出现的次数 --剑指offer
    最小的k个数 --剑指offer
    数组中出现次数超过一半的数字 --剑指offer
    redis击穿,穿透,雪崩,分布式锁,api(jedis,luttuce)
    Java创建数据库新建表及初始化表
    generatorConfig.xml自动生成实体类,dao和xml
  • 原文地址:https://www.cnblogs.com/dianming/p/6602537.html
Copyright © 2011-2022 走看看