runtime是一个很有意思的东西,如果你学iOS开发很经常就会用到或被问到runtime。那么runtime是什么呢,如何去了解它。
runtime:中文名 运行时,系统在编译时留下的一些 类型,操作在运行的时候动态去分析,处理,这也说明了object-c是一个动态语言。(swift与之不同,swift虽然可以通过调用oc的runtime,但是swift本身是静态语言。但是却通过能够和oc交互变成了具有动态特性的静态语言,这是闲话,不扯了)。
要了解runtime,知道runtime是什么。我觉得最关键的是看 objc/objc.h,objc/runtime.h文件。
首先要知道object-c底层是用c,c++写的
A. objc.h:
1、objc.h文件里面定义了一个id 是一个objc_object结构体指针类型,结构体中又一个isa这样的成员,isa是一个Class类型。而Class是 objc_class * 类型
也就是说一个 oc中的object其实就是一个带有objc_class*成员,并由这个objc_class*类型的成员来解释这个object是什么东西,包括这个object是什么类型,有什么方法。方法参数组成,有什么协议,类别等。
p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px Menlo; color: #a5b0bb }
span.s1 { color: #de38a5 }
span.s2 { }
typedef struct objc_class *Class;
p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px Menlo; color: #a5b0bb }
span.s1 { color: #de38a5 }
span.s2 { }
struct objc_object {
Class isa OBJC_ISA_AVAILABILITY;
};
2、然后我们来看 Class这个类型,Class这个类型是objc_class*的别名。具体意思不就是说是用objc_class这个结构体对应的指针类型。
3、接着是SEL, 跟Class差不多这个也是另外一个结构体指针的别名,这个对应的结构体叫做objc_selector.
其中objc_object可以在runtime中看到具体的结构。objc_selector我没找到在哪里,谁看到了提醒一下哦。
4、然后是方法实现的定义:
p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px Menlo; color: #4bd156 }
p.p2 { margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px Menlo; color: #eb905a }
p.p3 { margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px Menlo; color: #de38a5 }
span.s1 { }
span.s2 { color: #a5b0bb }
span.s3 { color: #8d8d8d }
/// A pointer to the function of a method implementation.
#if !OBJC_OLD_DISPATCH_PROTOTYPES
typedef void (*IMP)(void /* id, SEL, ... */ );
#else
typedef id (*IMP)(id, SEL, ...);
#endif
接着下面是定义了一些对方法名,变量的一些操作。
B.runtime.h
runtime.h文件中定义了很多的结构体和方法。
1、首先是给几个结构体指针类型定义了几个别名 objc_method * 对应Method, objc_ivar *对应Ivar,objc_catagory *对应 Catagory objc_property *对应objc_property_t 类型。
2、objc_class 结构体
p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px Menlo; color: #a5b0bb }
p.p2 { margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px Menlo; color: #a5b0bb; min-height: 16.0px }
p.p3 { margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px Menlo; color: #eb905a }
span.s1 { color: #de38a5 }
span.s2 { }
struct objc_class {
Class isa OBJC_ISA_AVAILABILITY;
#if !__OBJC2__
Class super_class OBJC2_UNAVAILABLE;
const char *name OBJC2_UNAVAILABLE;
long version OBJC2_UNAVAILABLE;
long info OBJC2_UNAVAILABLE;
long instance_size OBJC2_UNAVAILABLE;
struct objc_ivar_list *ivars OBJC2_UNAVAILABLE;
struct objc_method_list **methodLists OBJC2_UNAVAILABLE;
struct objc_cache *cache OBJC2_UNAVAILABLE;
struct objc_protocol_list *protocols OBJC2_UNAVAILABLE;
#endif
} OBJC2_UNAVAILABLE;
从上面这个结构中可以看到一个objc_class中有一个 Class 定义的isa成员,这个成员其实在A中可以看出来 其实也是一个objc_class *这种类型。(这种定义方式在我们学习c++的时候有学过。谭浩强的《面向对象c++》..)
然后我们这时要知道object-c里面的类和实例其实都是一个定义的对象,而且对应的指针是isa .也就是说系统 像malloc这个操作后会把 指针存到这个 isa中。
这样其实object-c里面的类和对象其实都是通过结构体指针来实现的。
然后我们再看 objc_class中的结构其中包括了 父类,类名,版本, 示例大小,实例中包含的变量列表,方法列表,缓存,协议列表。这些东西
在往下看 可以看到Protocol是一个objc_object类型,然后通过objc_object里面的isa 指针保存对应的名字,方法,变量等。所以通过这个你可以认识到定义一个协议是可以往里面加你要的属性的。
然后往下
objc_method_description的结构体这个东西定义了方法有方法名和方法类型
objc_property_attribute_t这个结构体定义了属性的特点包括需要有 名称 和 值。
再往下看有很多对实例在运行时的操作,这里我就省略了。又一个方法叫
p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px Menlo; color: #a5b0bb }
span.s1 { }
imp_implementationWithBlock
从这里可以拿到一个block的对应的实现的指针。(block是一个对象)
再往下有给object设置关联的方法,这些操作就是平时用到的在类别中如何给一个类添加一些属性(类别中是不能添加属性的,不过通过这个方法可以为你定义的属性的set,和get方法相当于重写的操作。然后实现了一个类别的属性)
p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px Menlo; color: #a5b0bb }
span.s1 { }
objc_setAssociatedObject
p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px Menlo; color: #a5b0bb }
span.s1 { }
objc_getAssociatedObject
p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px Menlo; color: #a5b0bb }
span.s1 { }
objc_removeAssociatedObjects
再往下走又是一堆结构体 protocol_list, objc_catagory, objc_ivar, objc_ivar_list, objc_method, objc_method_list, objc_cache, objc_module.
这些结构体分别对应的定义了我们在oc中经常用到的 类别,方法等东西的结构(含糊的讲一下,有点多)
总结一下,也就是说其实ios的runtime是通过很多个 struct类型来缓存对应的结构并在运行的时候通过这些结构特征和对应的指针来分析并进行对应的操作。
所以多看里面的结构组成就对了。
以上属于个人理解
推荐一篇讲的蛮详细的(http://chun.tips/blog/2014/11/06/bao-gen-wen-di-objective[nil]c-runtime(3)[nil]-xiao-xi-he-category/)
如果想更深入了解具体内部实现原理,就要看opensource.apple.com里面的内容了,如: https://opensource.apple.com//source/objc4/objc4-706/runtime/
p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px Menlo; color: #a5b0bb }
span.s1 { }
p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px Menlo; color: #a5b0bb }
span.s1 { color: #de38a5 }
span.s2 { }
p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px Menlo; color: #4bd156 }
p.p2 { margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px Menlo; color: #a5b0bb }
p.p3 { margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px Menlo; color: #a5b0bb; min-height: 16.0px }
p.p4 { margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px Menlo; color: #eb905a }
p.p5 { margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px Menlo; color: #8d8d8d }
p.p6 { margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px Menlo; color: #de38a5 }
span.s1 { }
span.s2 { color: #de38a5 }
span.s3 { color: #a5b0bb }
span.Apple-tab-span { white-space: pre }
p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px Menlo; color: #a5b0bb }
span.s1 { }
关于iOS的runtime的更多相关文章
-
ios之runtime学习
今天学习了一下ios的runtime,看了其他博主的博客写的很不错,自己就不班门弄斧了,仅在此转载: 1.关于oc中类和元类:http://husbandman.diandian.com/post/2 ...
-
IOS 中runtime 不可变数组__NSArray0 和__NSArrayI
IOS 中runtime 不可变数组__NSArray0 和__NSArrayI 大家可能都遇到过项目中不可变数组避免数组越界的处理:runtime,然而有时候并不能解决所有的问题,因为类簇不一样 # ...
-
iOS运用runtime全局修改UILabel的默认字体
iOS运用runtime全局修改UILabel的默认字体 一.需求背景介绍 在项目比较成熟的基础上,遇到了这样一个需求,应用中需要引入新的字体,需要更换所有Label的默认字体,但是同时,对于一些特殊 ...
-
iOS开发-Runtime详解
iOS开发-Runtime详解 简介 Runtime 又叫运行时,是一套底层的 C 语言 API,其为 iOS 内部的核心之一,我们平时编写的 OC 代码,底层都是基于它来实现的.比如: [recei ...
-
iOS:runtime最全的知识总结
runtime 完整总结 好东西,应该拿出来与大家分享... 南峰子博客地址:http://southpeak.github.io/blog/categories/ios/ 原文链接:http://w ...
-
iOS - OC RunTime		运行时
1.运行时的使用 向分类中添加属性 // 包含运行时头文件 #import <objc/runtime.h> /* void objc_setAssociatedObject(id obj ...
-
iOS 开发-- Runtime 1小时入门教程
1小时让你知道什么是Objective-C Runtime,并对它有一定的基本了解,可以在开发过程中运用自如. 三.Objective-C Runtime到底是什么东西? 简而言之,Objective ...
-
iOS之RunTime浅谈
首先说一下什么是runtime:RunTime简称运行时.就是系统在运行的时候的一些机制,其中最主要的是消息机制.对于C语言,函数的调用 在编译的时候会决定调用哪个函数( C语言的函数调用请看这里 ) ...
-
iOS利用Runtime自定义控制器POP手势动画
前言 苹果在iOS 7以后给导航控制器增加了一个Pop的手势,只要手指在屏幕边缘滑动,当前的控制器的视图就会跟随你的手指移动,当用户松手后,系统会判断手指拖动出来的大小来决定是否要执行控制器的Pop操 ...
随机推荐
-
BZOJ 3112: [Zjoi2013]防守战线 [单纯形法]
题目描述 战线可以看作一个长度为n 的序列,现在需要在这个序列上建塔来防守敌兵,在序列第i 号位置上建一座塔有Ci 的花费,且一个位置可以建任意多的塔,费用累加计算.有m 个区间[L1, R1], [ ...
-
wechat开发
1.easywechat安装 2.weichat打通服务器 function getTest(Request $request){ $token = 'zhenhaokeji'; $data = $r ...
-
Javascript的精华啊【如果以后我看到了或者想到了再继续补吧】
我不过略有一些讨人喜欢的地方而已,怎么会有什么迷人的魔力呢? 一.语法 JS只有一个数字类型,64位浮点数,所以1和1.0是相同的.为什么这么设计:防止短整型的溢出. 二.对象 1.通常将一个对象的值 ...
-
C#跟踪和调试程序-Debug类使用
摘要: 怎样在 Visual C# .NET 中跟踪和调试?当程序运行时,您可以使用 Debug 类的方法来生成消息,以帮助您监视程序执行顺序.检测故障或提供性能度量信息.默认情况下,Debug 类产 ...
-
认识与学习BASH
应用程序在最外面,就如同鸡蛋的外壳一样,因此被称呼为shell(壳程序).其实壳程序的功能只是提供操作系统的一个接口. 应用程序 ↓ 操作系统(系统呼叫+核心) ↓ 硬件 linux预设的shell就 ...
-
frontend http 前端名字定义问题
https://www.winfae.com/admin/api/menu haproxy 日志: Jun 24 13:04:49 localhost haproxy[14817]: 115.236. ...
-
JAVA_SE基础——61.字符串入门
public class Demo1 { public static void main(String[] args) { String str1 = "hello"; Strin ...
-
tomcat中的线程问题
看这篇文章之前,请先阅读: how tomcat works 读书笔记 十一 StandWrapper 上 地址如下: http://blog.csdn.net/dlf123321/article/d ...
-
[luogu1341][无序字母对]
luogu1341 思路 欧拉回路和欧拉路的裸题,首先判断是否存在欧拉路或者欧拉回路.当且仅当途中每个点的度数都为偶数时,存在欧拉回路.当且仅当图中度数为奇数的点的个数为2时,存在欧拉路.如果存在欧拉 ...
-
ln 链接命令 简要说明 软硬链接关系说明
ln [选项] 目标 -s 创建符号链接(软链接) -f 强制创建链接 -i 覆盖前先询问 -v 显示创建链接过程 ln命令不能对目录创建硬链接,但可以创建软链接,对目录的软链接经常被用到 删除软链接 ...