关于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操 ...
随机推荐
- Android自用-----WindowManager$BadTokenException: Unable to add window -- token null is not for an application
转自http://www.cnblogs.com/oakpip/archive/2011/04/06/2007310.html 错误产生: private Context mcontext; @Ove ...
- IOS学习之初识KVO
什么是KVO? KVO(Key-Value Observing)键值观察,是一种通过对对象的某一个属性添加观察者,一旦这个属性值发生变化,就会通知当前观察者的一种机制. 该如何使用? 1.注册,指定被 ...
- 解决Select2控件不能在jQuery UI Dialog中不能搜索的bug
本文使用博客园Markdown编辑器进行编辑 1.问题呈现 项目中使用了jQuery UI的Dialog控件,一般用来处理需要提示用户输入或操作的简单页面.逻辑是修改一个广告的图片和标题. 效果截图如 ...
- MyCAT日志分析
MyCAT日志对于了解MyCAT的运行信息不可获取,譬如MyCAT是否采用读写分离,对于一个查询语句,MyCAT是怎样执行的,每个分片会分发到哪个节点上等等. 默认是info级别,通过log4j.xm ...
- JavaScript的Tab切换
在网页设计中经常要用到tab切换,遂整理了一下常用的两种方法. 先看一下示例代码: HTML: <!doctype html> <html lang="en"&g ...
- Callbacks vs Events
前言:本文翻译自Dean Edwards的一篇文章,原文地址:http://dean.edwards.name/weblog/2009/03/callbacks-vs-events/. 文章主要指出了 ...
- Tomcat服务器本地的搭建,以及在 IDEA软件下的配置,以及项目的测试运行(基于supermvc框架下的web)
一.声明 使用了基于springmvc的supermvc的web框架.实习公司的框架. 二.tomact的下载与安装 1选择适合自己电脑配置的jdk和jre版本(截图来自tomcat的官方网站http ...
- 【JVM】JVM系列之执行引擎(五)
一.前言 在了解了类加载的相关信息后,有必要进行更深入的学习,了解执行引擎的细节,如字节码是如何被虚拟机执行从而完成指定功能的呢.下面,我们将进行深入的分析. 二.栈帧 我们知道,在虚拟机中与执行方法 ...
- iis7.0上发布mvc4.0网站
步骤如下: 1.右击需要发布的项目,在弹出的菜单中选择“发布...”选项 2.在“发布web”对话框中进行设置,配置文件名称默认为“配置文件1”可以修改为需要的名字,以便识别,也可以不改.发布方法选择 ...
- github生成静态博客
github生成静态博客很简单. 1.确认你知道你github的用户名,我的叫做chenxing12 2.创建一个项目名字叫做:用户名.github.io 我的用户名叫做chenxing12,所以我创 ...