关于iOS的runtime
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操 ...
随机推荐
- invalidate()和postInvalidate() 的区别及使用
Android提供了Invalidate方法实现界面刷新,但是Invalidate不能直接在线程中调用,因为他是违背了单线程模型:Android UI操作并不是线程安全的,并且这些操作必须在UI线程中 ...
- iOS开发之地图与定位
无论是QQ还是微信的移动客户端都少不了定位功能,之前在微信demo中没有添加定位功能,今天就写个定位的小demo来了解一下定位和地图的东西.地图和定位看上去是挺高大上一东西,其实用法比TableVie ...
- 延时调用--deferred.js原码分析
有些时候,我们需要等待上一个操作完成之后,才能进行下一步的操作.比如Ajax实现自动提交表单操作的时候,程序需要等待,一旦有返回结果了,则继续进行一下步操作. 这时deferred.js这个库就产生了 ...
- [Keras] mnist with cnn
典型的卷积神经网络. Keras傻瓜式读取数据:自动下载,自动解压,自动加载. # X_train: array([[[[ 0., 0., 0., ..., 0., 0., 0.], [ 0., 0. ...
- java中的list时间排序
最初设想使用:时间long型 private void testTimes() throws InterruptedException{ Calendar cal=Calendar.getInstan ...
- Full Gc经历分析
背景: 个别机器:内存突然上升,cpu利用率升高. 解决过程 1. jmap dump整个内存镜像 2. 整个文件700多M,使用Jhat打不开 3. 换heapanalyzer,能打开,但没有分析出 ...
- Markdown 语法整理
Markdown 语法整理 白宁超 2015年7月24日14:57:49 一.字体设置 A First Level Header == A Second Level Header -- # 标题 ## ...
- 如何用easyui+JAVA 实现动态拼凑datagrid表格
先给大家看一看效果,最近一段时间都在研究这个东西. 如果我把日期间隔选宽呢?比如5月日到5月5日?下面给大家看看效果,不用担心哦 看到了吧,哈哈,这个日期都是动态生成的,下面就来跟大家分享一下这个的实 ...
- PHP之call user func()函数
在实际开发中通常会遇到这样的问题,决定调用某个函数是通过传入的参数决定的,例如: $functionName=$_post['functionName']; 接着我们需要访问一个叫$functionN ...
- jQuery-1.9.1源码分析系列(四) 缓存系统
先前在分析Sizzle的时候分析到Sizzle有自己的缓存机制,点击这里查看.不过Sizzle的缓存只是对内使用的(内部自己存,自己取).接下来分析jQuery可以对外使用的缓存(可存可取). 首先需 ...