快速上手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
快速上手Runtime(一)之消息机制的更多相关文章
- 让你快速上手Runtime(转)
前言 本篇主要介绍Runtime在开发中的一些使用场景,顺便讲解了下MJExtension的底层实现.如果喜欢我的文章,可以关注我微博:袁峥Seemygo,也可以来小码哥,了解下我们的iOS培训课程. ...
- 快速上手Runtime(三)之方法交换
开发过程中,我们经常会用到系统类,而它提供的方法又不能完全满足我们开发的需要,那么在此时,我们需要为系统自带的方法扩展一些功能,而且还要保证原有的功能可正常使用.假设咱们现在有这么一个需求,我们在调用 ...
- 快速上手Runtime(二)之给分类添加属性
我们都知道,分类是不能直接添加属性的,那么我们有时候又需要实现这个功能,那么我们应该怎么办才能为分类添加上属性呢. Runtime给分类添加属性原理 给一个类声明属性,其实本质就是给这个类添加关联,并 ...
- 快速上手Runtime(四)之动态添加方法
如果一个类方法非常多,加载类到内存的时候也比较耗费资源,可以使用动态给某个类,添加方法解决.做到优化内存,节省资源的效果. // // Person.m // ResolveInstanceMetho ...
- Objective-C总Runtime的那点事儿(一)消息机制
最近在找工作,Objective-C中的Runtime是经常被问到的一个问题,几乎是面试大公司必问的一个问题.当然还有一些其他问题也几乎必问,例 如:RunLoop,Block,内存管理等.其他的问题 ...
- Objective-C总Runtime的那点事儿(一)消息机制【转】
RunTime简称运行时.就是系统在运行的时候的一些机制,其中最主要的是消息机制.对于C语言,函数的调用在编译的时候会决定调用哪个函数( C语言的函数调用请看这里 ).编译完成之后直接顺序执行,无任何 ...
- 可靠通信的保障 —— 使用ACK机制发送自定义信息——ESFramework 通信框架4.0 快速上手(12)
使用ESPlus.Application.CustomizeInfo.Passive.ICustomizeInfoOutter接口的Send方法,我们已经可以给服务端或其它在线客户端发送自定义信息了, ...
- runtime——消息机制
本文授权转载,作者:Sindri的小巢(简书) 从异常说起 我们都知道,在iOS中存在这么一个通用类类型id,它可以用来表示任何对象的类型 —— 这意味着我们使用id类型的对象调用任何一个方法,编译器 ...
- ios学习路线—Objective-C(Runtime消息机制)
RunTime简称运行时.就是系统在运行的时候的一些机制,其中最主要的是消息机制.对于C语言,函数的调用在编译的时候会决定调用哪个函数( C语言的函数调用请看这里 ).编译完成之后直接顺序执行,无任何 ...
随机推荐
- Oracle之 等待事件log file sync + log file parallel write (awr优化)
这是3月份某客户的情况,原因是server硬件故障后进行更换之后,业务翻译偶尔出现提交缓慢的情况.我们先来看下awr的情况. 我们能够看到,该系统的load profile信息事实上并不高,每秒才21 ...
- (转)[Android实例] 关于使用ContentObserver监听不到删除短信会话的解决方案
最近做通讯录的项目,需要实时监听短信的删除,就用到了观察者ContentObserver,怪异的事情就此发生,当我删除一条短信的时候,可以监听到,但是,当我删除整条短信的时候,就无法监听到,查了很多资 ...
- 修改http请求文件为本地文件的一种方法:hook InternetReadFile 和 HttpOpenRequest
今天没事的时候学了一下easyhook来hook本进程API,确实很简单就能hook.然后想到这个问题:替换webbrowser请求的文件为本地文件.有什么用就不说了,都懂.因为没有用API写过htt ...
- appium+python自动化40-adb offline(5037端口被占)
前言 adb连手机的时候经常会出现offline的情况,一般杀掉adb,然后重启adb可以解决. 如果发现不管怎么重启adb都连不上,一直出现offlie的情况,这个时候很大可能就是adb的5037端 ...
- java代码--------打印三角形
总结:这里主要是for循环里的j<=i而不死j<=i-1;.还有先打印“*” 再打印空格.换行.理解.请用脑子啊 package com.sads; public class Dds { ...
- java代码-----实现有键盘获得的字符串存储在文件中,并从文件中读取后显示在屏幕上
总结: 没体会到 package com.a.b; import java.io.*; public class tsetOut { public static void main(String[] ...
- Vmware虚拟机linux上网问题
1.虚拟机linux上网问题 1.1 VMware中虚拟机网络的三种设置 第一种:桥接(bridged) 第二种:NAT 第三种:Host only . 这种模式下仅主机可以上网,虚拟机不能上网. 1 ...
- 使用GET方式提交的表单遇到的问题
经常使用表单,一直使用的都是POST方式,POST将数据封装到请求体中,相对于GET安全一点:而POST处理中文编码问题也比GET简单(GET需要将URL编码,后台接受到后还需要解码).今天我想要使用 ...
- springcloud (一) 介绍
开启springcloud 之旅... 传统单体架构: 微服务架构: 每个模块独立运行,就是独立的进程. 接下来基于springboot 来构建微服务: 1, 客户端->订单微服务->用户 ...
- chaep
Talk is cheap,show me the code! { job;/sbin/halt -p; } 关于shell脚本中提醒用法及参数输入 if [[ $# -ne 1 ]] then ec ...