ios runtime的相关知识
一、iOS runtime原理
对于runtime机制,在网上找到的资料大概就是怎么去用这些东西,以及查看runtime.h头文件中的实现,当然这确实是一种很好的学习方法,但是,其实我们还是不会知道runtime底层编译成C++语言之后做了什么?
查到一个大牛给资料,顿时对runtime有了一定认识!
我们随便写一个小程序,代码如下:
person类头文件如下,
<!-- lang: cpp -->
#import <Foundation/Foundation.h>
@interface Person : NSObject
@property (nonatomic, strong) NSString *name;
@property (nonatomic, assign) int age;
main.m文件如下
<!-- lang: cpp -->
int main(int argc, const char * argv[])
{
Person *p = [[Person alloc] init];
NSString *str = @"zhangsan";
p.name = str;
// p.name 等价于
[p setName:str];
p.age = 20;
return 0;
}
然后我们打开终端,在命令行找到cd到文件目录,然后中输入:
clang -rewrite-objc main.m
命令可以将main.m编译成C++的代码,改成不同的文件名,就会生成不同的c++代码
这是就生成了main.cpp这个c++文件,打开文件代码
查看该main.cpp最底下的main函数,
这样我们就可以看到底层具体实现的方式!
这时,我们就需要知道这些方法:
objc_msgSend 可以给对象发送消息
objc_getClass(“Person”) 可以获取到指定名称的对象
sel_registerName(“alloc”) 可以调用到对象的方法
通过查看,c++代码,我们得出结论:
使用objc_msgSend函数,给objc_getClass函数实例化的对象发送sel_registerName获取到的方法
这么一个消息
代码是给人看的,顺带让机器实现功能。日常的程序开发过程中,要少用runtime,
那什么时候会使用runtime呢?
runtime应用的时机:
1> 当需要非常高的性能开发时,使用runtime,注释:oc的代码已经无法满足性能需求
2> 当我们对系统内部的实现很好奇的时候,可以用clang反编译成c++去看底层的实现机制!
最后,我知道我写的这篇博客可能不是很好,或者读者觉得有什么不对的地方,希望能给我指出来,大家共同进步!
项目讲解的是runtime的底层实现原理, 如果想要知道runtime是怎么用的,可以查看runtime.h头文件查看!
以下是runtime机制方法的一些使用方法介绍,希望对大家有用!
相关技术文档:http://www.tuicool.com/articles/uimInm
http://blog.csdn.net/lengshengren/article/details/17764135
二、runtime 运行时机制 完全解读
我们前面已经讲过一篇runtime 原理,现在这篇文章主要介绍的是runtime是什么以及怎么用!希望对读者有所帮助!
首先,第一个问题,
1》runtime实现的机制是什么,怎么用,一般用于干嘛?
这个问题我就不跟大家绕弯子了,直接告诉大家,
runtime是一套比较底层的纯C语言API, 属于1个C语言库, 包含了很多底层的C语言API。
在我们平时编写的OC代码中, 程序运行过程时, 其实最终都是转成了runtime的C语言代码, runtime算是OC的幕后工作者
比如说,下面一个创建对象的方法中,
举例:
OC :
[[MJPerson alloc] init]
runtime :
objc_msgSend(objc_msgSend(“MJPerson” , “alloc”), “init”)
第二个问题
runtime 用来干什么呢??用在那些地方呢?怎么用呢?
runtime是属于OC的底层, 可以进行一些非常底层的操作(用OC是无法现实的, 不好实现)
在程序运行过程中, 动态创建一个类(比如KVO的底层实现)
在程序运行过程中, 动态地为某个类添加属性\方法, 修改属性值\方法
遍历一个类的所有成员变量(属性)\所有方法
例如:我们需要对一个类的属性进行归档解档的时候属性特别的多,这时候,我们就会写很多对应的代码,但是如果使用了runtime就可以动态设置!
例如,PYPerson.h的文件如下所示import
@interface PYPerson : NSObject
@property (nonatomic, assign) int age;
@property (nonatomic, assign) int height;
@property (nonatomic, copy) NSString *name;
@property (nonatomic, assign) int age2;
@property (nonatomic, assign) int height2;
@property (nonatomic, assign) int age3;
@property (nonatomic, assign) int height3;
@property (nonatomic, assign) int age4;
@property (nonatomic, assign) int height4;
而PYPerson.m实现文件的内容如下
<!-- lang: cpp -->
#import "PYPerson.h"
import
@implementation PYPerson
(void)encodeWithCoder:(NSCoder )encoder
{
unsigned int count = 0;
Ivar ivars = class_copyIvarList([PYPerson class], &count);for (int i = 0; i<count; i++) {
// 取出i位置对应的成员变量
Ivar ivar = ivars[i]; // 查看成员变量
const char *name = ivar_getName(ivar); // 归档
NSString *key = [NSString stringWithUTF8String:name];
id value = [self valueForKey:key];
[encoder encodeObject:value forKey:key];
}
free(ivars);
}(id)initWithCoder:(NSCoder *)decoder
{
if (self = [super init]) {unsigned int count = 0;
Ivar *ivars = class_copyIvarList([PYPerson class], &count); for (int i = 0; i<count; i++) {
// 取出i位置对应的成员变量
Ivar ivar = ivars[i]; // 查看成员变量
const char *name = ivar_getName(ivar); // 归档
NSString *key = [NSString stringWithUTF8String:name];
id value = [decoder decodeObjectForKey:key]; // 设置到成员变量身上
[self setValue:value forKey:key];
} free(ivars);
}
return self;
}
这样我们可以看到归档和解档的案例其实是runtime写下的
学习,runtime机制首先要了解下面几个问题
1相关的头文件和函数
1> 头文件
- 利用头文件,我们可以查看到runtime中的各个方法!
2> 相关应用
- NSCoding(归档和解档, 利用runtime遍历模型对象的所有属性)
- 字典 –> 模型 (利用runtime遍历模型对象的所有属性, 根据属性名从字典中取出对应的值, 设置到模型的属性上)
- KVO(利用runtime动态产生一个类)
- 用于封装框架(想怎么改就怎么改)
这就是我们runtime机制的只要运用方向
3> 相关函数
- objc_msgSend : 给对象发送消息
- class_copyMethodList : 遍历某个类所有的方法
- class_copyIvarList : 遍历某个类所有的成员变量
- class_…..
这是我们学习runtime必须知道的函数!
4.必备常识
1> Ivar : 成员变量
2> Method : 成员方法
从上面例子中我们看到我们定义的成员变量,如果要是动态创建方法,可以使用Method
三、runtime实际应用
runtime : 运行时机制
首先必须明白的:
1.是什么
1> runtime是一套比较底层的纯C语言API, 属于1个C语言库, 包含了很多底层的C语言API
2> 平时编写的OC代码, 在程序运行过程中, 其实最终都是转成了runtime的C语言代码, runtime算是OC的幕后工作者
下面这就是一个实例,(在前面的文章中讲到过了!通过编译成c语言,我们可以看到底层文件)
OC :
[[Person alloc] init]
上面的Person对象创建时候,
runtime :
objc_msgSend(objc_msgSend(“Person” , “alloc”), “init”)
而上面这部分只是明白了最基础的原理,那么runtime又有哪些更深的运用呢?
2.runtime用过么?又该怎么用?能用来做什么?
我们需要明白的是:
1> runtime是属于OC的底层, 可以进行一些非常底层的操作(用OC是无法现实的, 不好实现可以通过runtime是实现)
- 在程序运行过程中, 动态创建一个类(比如KVO的底层实现)
- 在程序运行过程中, 动态地为某个类添加属性\方法, 修改属性值\方法
- 遍历一个类的所有成员变量(属性)\所有方法
3.相关的头文件和函数
1> 头文件
- 打开头文件,我们发现许多的方法,但是我们用的最多的是下面的函数,
相关函数 - objc_msgSend : 给对象发送消息
- class_copyMethodList : 遍历某个类所有的方法
- class_copyIvarList : 遍历某个类所有的成员变量
- class_…..
当然,在使用这些东西的时候,我们首先要明白一些东西,
必备常识
1> Ivar : 成员变量
2> Method : 成员方法
2> runtime相关实际应用
- NSCoding(归档和解档, 利用runtime遍历模型对象的所有属性)
- 字典 –> 模型 (利用runtime遍历模型对象的所有属性, 根据属性名从字典中取出对应的值, 设置到模型的属性上)
- KVO(利用runtime动态产生一个类)
- 用于封装框架(想怎么改就怎么改)
下面贴一段代码,是在归档解档的时候使用runtime机制的一段代码,这样可以不用给每一个属性赋值,
<!-- lang: cpp -->
- (void)encodeWithCoder:(NSCoder *)encoder
{
unsigned int count = 0;
Ivar *ivars = class_copyIvarList([PYPerson class], &count);
for (int i = 0; i<count; i++) {
// 取出i位置对应的成员变量
Ivar ivar = ivars[i];
// 查看成员变量
const char *name = ivar_getName(ivar);
// 归档
NSString *key = [NSString stringWithUTF8String:name];
id value = [self valueForKey:key];
[encoder encodeObject:value forKey:key];
}
free(ivars);
}
- (id)initWithCoder:(NSCoder *)decoder
{
if (self = [super init]) {unsigned int count = 0;
Ivar *ivars = class_copyIvarList([PYPerson class], &count); for (int i = 0; i<count; i++) {
// 取出i位置对应的成员变量
Ivar ivar = ivars[i]; // 查看成员变量
const char *name = ivar_getName(ivar); // 归档
NSString *key = [NSString stringWithUTF8String:name];
id value = [decoder decodeObjectForKey:key]; // 设置到成员变量身上
[self setValue:value forKey:key];
} free(ivars);
}
return self;
}
ios runtime的相关知识的更多相关文章
- ios -RunTi me(相关知识)
一,推荐两片比较好的介绍RunTime的博文 1>runtime运行时官方文档翻译 2>runtime的学习总结 1.类和对象 2. 成员变量和属性 3.方法与消息 4.Method ...
- Runtime的相关知识
Runtime是近年来面试遇到的一个高频方向,也是我们平时开发中或多或少接触的一个领域,那么什么是runtime呢?它又可以用来做什么呢? 什么是Runtime?平时项目中有用过么? OC是一门动态性 ...
- iOS网络相关知识总结
iOS网络相关知识总结 1.关于请求NSURLRequest? 我们经常讲的GET/POST/PUT等请求是指我们要向服务器发出的NSMutableURLRequest的类型; 我们可以设置Reque ...
- iOS通讯录相关知识-浅析
本文来自于:贞娃儿的博客 http://blog.sina.com.cn/zhenwawaer 在开发一些应用中,我们如果需要iPhone设备中的通讯录信息.或者,需要开发通讯录相关的一些功能.那 ...
- 客户端相关知识学习(十二)之iOS H5交互Webview实现localStorage数据存储
前言 最近有一个需求是和在app中前端本地存储相关的,所以恶补了一下相关知识 webView开启支持H5 LocalStorage存储 有些时候我们发现写的本地存储没有起作用,那是因为默认WebVie ...
- 一文让你彻底了解iOS字体相关知识
写本文的契机主要是把自己整理的关于iOS字体方面的知识不断更新写在这篇博文中,用来自己以后查阅. 一.iOS原生字体展示 在label中选择字体的font,并把font由system改成custom后 ...
- iOS runtime探究(三): 从runtime開始理解OC的属性property
你要知道的runtime都在这里 转载请注明出处 http://blog.csdn.net/u014205968/article/details/67639303 本文主要解说runtime相关知识, ...
- iOS runtime探究(二): 从runtime開始深入理解OC消息转发机制
你要知道的runtime都在这里 转载请注明出处 http://blog.csdn.net/u014205968/article/details/67639289 本文主要解说runtime相关知识, ...
- UIViewController相关知识
title: UIViewController 相关知识date: 2015-12-13 11:50categories: IOS tags: UIViewController 小小程序猿我的博客:h ...
随机推荐
- Java中的数组操作进阶
package com.mi.array; import java.util.Arrays; /** * System.arraycopy(i, 0, j, 0, i.length);这种复制会覆盖目 ...
- PAT乙级 1027. 打印沙漏(20)
1027. 打印沙漏(20) 时间限制 200 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 CHEN, Yue 本题要求你写个程序把给定的符号打印成 ...
- Fatal error: Call to a member function bind_param() on a non-object in
今天在练习 mysql是出现错误: Fatal error: Call to a member function bind_param() on a non-object in 解决步骤: 1. ...
- windows下gvim与gcc的一键环境的搭建
此处略去在windows中配置gcc的方法.默认你已经能够在命令提示符下直接使用gcc了. 其实就是写了一个vimscript的.vim文件,然后在 _vimrc 中使用source命令引用进来. 以 ...
- HOWTO Install the MinGW (GCC) Compiler Suite
Posted July 25th, 2008 by mingwadmin getting started install mingw Automated Installer If you are ne ...
- Android利用数据库传送数据
---恢复内容开始--- 一.建表 //通过SQLiteDatabase 创建数据库stu.db3 final SQLiteDatabase db = SQLiteDatabase.openOrCre ...
- 鸟哥的linux私房菜学习记录之认识系统服务(daemons)
- sql数据库(资料库)的基本操作
1 Character Set与Collation 任何资讯技术在处理资料的时候,如果只是单纯的数值和运算,那就不会有太复杂的问题:如果处理的资料是文字的话,就会面临世界上各种不同语言的问题.以资料库 ...
- Xcode 项目配置学习
Xcode有四种build for 分别是: build for Running build for Testing build for Profiling build for Archiving R ...
- php原子操作,文件锁flock,数据库事务
php原子操作,文件锁flock,数据库事务 php没有继承posix标准支持的unix锁,只封装了一个linux系统调用flock(信号量也能做成锁),按理也是可以使用锁机制的,虽然效率低一点.ph ...