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类

  1. #import <Foundation/Foundation.h>
  2.  
  3. @interface Person : NSObject
  4.  
  5. - (void)name;
  6.  
  7. + (void)name;
  8.  
  9. @end
  10.  
  11. #import "Person.h"
  12.  
  13. @implementation Person
  14.  
  15. - (void)name{
  16. NSLog(@"对象方法---I'm doman");
  17. }
  18.  
  19. + (void)name{
  20. NSLog(@"类方法---I'm doman");
  21.  
  22. }
  23.  
  24. @end

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

  1. #pragma mark 如果是自己测试,请先移步Build Setting -> 搜索msg -> 设置属性为No
  2.  
  3. //对象方法做法1
  4. Person *p1 = [[Person alloc] init];
  5. [p1 name];
  6.  
  7. //对象方法做法2
  8. Person *p2 = [[Person alloc] init];
  9. [p2 performSelector:@selector(name)];
  10. // SEL:方法编号,根据方法编号就可以找到对应方法实现,此方法其实就是运用了运行时。
  11.  
  12. //类方法做法1
  13. [Person name];
  14.  
  15. //类方法做法2--通过类对象调用
  16. [[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开头.

  1. // 让person发送消息-对象方法
  2. Person *p3 = [[Person alloc]init];
  3.  
  4. objc_msgSend(p3,@selector(name));
  5.  
  6. //类方法使用runtime
  7. // 获取类对象
  8. Class personClass = [Person class];
  9.  
  10. objc_msgSend(personClass, @selector(name));

调用结果:

  1.  
  1. Demo 地址:https://github.com/domanc/Runtime_Person.git

快速上手Runtime(一)之消息机制的更多相关文章

  1. 让你快速上手Runtime(转)

    前言 本篇主要介绍Runtime在开发中的一些使用场景,顺便讲解了下MJExtension的底层实现.如果喜欢我的文章,可以关注我微博:袁峥Seemygo,也可以来小码哥,了解下我们的iOS培训课程. ...

  2. 快速上手Runtime(三)之方法交换

    开发过程中,我们经常会用到系统类,而它提供的方法又不能完全满足我们开发的需要,那么在此时,我们需要为系统自带的方法扩展一些功能,而且还要保证原有的功能可正常使用.假设咱们现在有这么一个需求,我们在调用 ...

  3. 快速上手Runtime(二)之给分类添加属性

    我们都知道,分类是不能直接添加属性的,那么我们有时候又需要实现这个功能,那么我们应该怎么办才能为分类添加上属性呢. Runtime给分类添加属性原理 给一个类声明属性,其实本质就是给这个类添加关联,并 ...

  4. 快速上手Runtime(四)之动态添加方法

    如果一个类方法非常多,加载类到内存的时候也比较耗费资源,可以使用动态给某个类,添加方法解决.做到优化内存,节省资源的效果. // // Person.m // ResolveInstanceMetho ...

  5. Objective-C总Runtime的那点事儿(一)消息机制

    最近在找工作,Objective-C中的Runtime是经常被问到的一个问题,几乎是面试大公司必问的一个问题.当然还有一些其他问题也几乎必问,例 如:RunLoop,Block,内存管理等.其他的问题 ...

  6. Objective-C总Runtime的那点事儿(一)消息机制【转】

    RunTime简称运行时.就是系统在运行的时候的一些机制,其中最主要的是消息机制.对于C语言,函数的调用在编译的时候会决定调用哪个函数( C语言的函数调用请看这里 ).编译完成之后直接顺序执行,无任何 ...

  7. 可靠通信的保障 —— 使用ACK机制发送自定义信息——ESFramework 通信框架4.0 快速上手(12)

    使用ESPlus.Application.CustomizeInfo.Passive.ICustomizeInfoOutter接口的Send方法,我们已经可以给服务端或其它在线客户端发送自定义信息了, ...

  8. runtime——消息机制

    本文授权转载,作者:Sindri的小巢(简书) 从异常说起 我们都知道,在iOS中存在这么一个通用类类型id,它可以用来表示任何对象的类型 —— 这意味着我们使用id类型的对象调用任何一个方法,编译器 ...

  9. ios学习路线—Objective-C(Runtime消息机制)

    RunTime简称运行时.就是系统在运行的时候的一些机制,其中最主要的是消息机制.对于C语言,函数的调用在编译的时候会决定调用哪个函数( C语言的函数调用请看这里 ).编译完成之后直接顺序执行,无任何 ...

随机推荐

  1. UVA12716 GCD XOR 数论数学构造

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/u010682557/article/details/36204645 题目给你一个N,让你求 两个数 ...

  2. Android 系统四大组件

    Android 系统四大组件分别是活动(Activity).服务(Service).广播接收器(Broadcast Receiver)和内容提供器(Content Provider). 活动是所有 A ...

  3. 面向对象(PHP学习)

    在对超大型项目的开发过程中,如果使用面向过程地开发,代码量是非常的庞大,这将大量的用到判断和循环嵌套, 和很多很相似的代码,不仅使项目代码量更加的庞大,还不利于开发,重用及维护. 面向对象就能很好的解 ...

  4. 确保nginx安全的10个技巧

    Nginx是当今最流行的Web服务器之一.它为世界上7%的web流量提供服务而且正在以惊人的速度增长.它是个让人惊奇的服务器,我愿意部署它. 下面是一个常见安全陷阱和解决方案的列表,它可以辅助来确保你 ...

  5. DOM的基本概念

    1.DOM的基本概念 DOM是文档对象模型,这种模型为树模型:文档是指标签文档:对象是指文档中每个元素:模型是指抽象化的东西. 2.Window对象操作 一.属性和方法: 属性(值或者子对象): op ...

  6. Log4j.xml配置(rolling示例)

    Log4j.xml配置(很详细) <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE log4 ...

  7. 【学习笔记】FFT

    1.内容 由于noble_太懒 不想写了 非常好的博客: https://www.cnblogs.com/rvalue/p/7351400.html http://www.cnblogs.com/ca ...

  8. Java四舍五入 保留小数

    java 四舍五入保留小数   // 方式一: double f = 3.1516; BigDecimal b = new BigDecimal(f); double f1 = b.setScale( ...

  9. Entity Framework API介绍 -- DbSet<>().Find()

    过去我们常常使用Where或First(FirstOrDefault)方法来查找对应的实体,比如: var query = context.CertInfoMakeDetails.ToList().W ...

  10. Java多线程面试问题集锦

    参看:http://www.importnew.com/1428.html