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 ...
随机推荐
- 夺命雷公狗---node.js---22之项目的构建在node+express+mongo的博客项目7之数据的修改
在修改的时候和在PHP里面修改的一样,都是需要在列表页传个id过来才可以实现修改的,如下所示: 然后在后端接收到他传过来id的同时去读取该id的所有信息: 然后就开始写post处理数据方面的问题了,如 ...
- 亚马逊ec2服务器上无法使用sudo执行npm命令的解决办法
sudo ln -s /usr/local/bin/node /usr/bin/node sudo ln -s /usr/local/lib/node /usr/lib/node sudo ln -s ...
- rqnoj-342-最不听话的机器人-dp
dp[i][j][k][[l]: 执行第i步,执行到点(j,k),方向为l时,用的最大步数. 状态转移根据step[i]转移. #include<stdio.h> #include< ...
- android 项目学习随笔二十(屏幕适配)
1.图片适配 放入相同名称的资源文件,机器根据不同分辨率找相近的资源 240*320 ldpi 320*480 mdpi 480*800 hdpi 720*1280 xhdpi 2.布局适配 在不同的 ...
- 鸟哥的linux私房菜之vim
vim是vi的进阶版本
- linux设备驱动归纳总结(三):7.异步通知fasync【转】
本文转载自:http://blog.chinaunix.net/uid-25014876-id-62725.html linux设备驱动归纳总结(三):7.异步通知fasync xxxxxxxxxxx ...
- java几道简单的面试题目
1. 请问以下程序会输出什么? public class Test { public static void main(String[] args) { Par ...
- html插入视频
http://www.jb51.net/web/168548.html http://www.w3school.com.cn/html/html_media.asp
- rtc关机闹钟7 jni层 com_android_server_AlarmManagerService
frameworks/base/services/core/jni/com_android_server_AlarmManagerService.cpp int AlarmImplAlarmDrive ...
- Javascript中自动切换焦点
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title&g ...