一、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;

@end

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;

@end

而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; 
    }

@end

这样我们可以看到归档和解档的案例其实是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的相关知识的更多相关文章

  1. ios -RunTi me(相关知识)

    一,推荐两片比较好的介绍RunTime的博文    1>runtime运行时官方文档翻译 2>runtime的学习总结 1.类和对象 2. 成员变量和属性 3.方法与消息 4.Method ...

  2. Runtime的相关知识

    Runtime是近年来面试遇到的一个高频方向,也是我们平时开发中或多或少接触的一个领域,那么什么是runtime呢?它又可以用来做什么呢? 什么是Runtime?平时项目中有用过么? OC是一门动态性 ...

  3. iOS网络相关知识总结

    iOS网络相关知识总结 1.关于请求NSURLRequest? 我们经常讲的GET/POST/PUT等请求是指我们要向服务器发出的NSMutableURLRequest的类型; 我们可以设置Reque ...

  4. iOS通讯录相关知识-浅析

    本文来自于:贞娃儿的博客  http://blog.sina.com.cn/zhenwawaer  在开发一些应用中,我们如果需要iPhone设备中的通讯录信息.或者,需要开发通讯录相关的一些功能.那 ...

  5. 客户端相关知识学习(十二)之iOS H5交互Webview实现localStorage数据存储

    前言 最近有一个需求是和在app中前端本地存储相关的,所以恶补了一下相关知识 webView开启支持H5 LocalStorage存储 有些时候我们发现写的本地存储没有起作用,那是因为默认WebVie ...

  6. 一文让你彻底了解iOS字体相关知识

    写本文的契机主要是把自己整理的关于iOS字体方面的知识不断更新写在这篇博文中,用来自己以后查阅. 一.iOS原生字体展示 在label中选择字体的font,并把font由system改成custom后 ...

  7. iOS runtime探究(三): 从runtime開始理解OC的属性property

    你要知道的runtime都在这里 转载请注明出处 http://blog.csdn.net/u014205968/article/details/67639303 本文主要解说runtime相关知识, ...

  8. iOS runtime探究(二): 从runtime開始深入理解OC消息转发机制

    你要知道的runtime都在这里 转载请注明出处 http://blog.csdn.net/u014205968/article/details/67639289 本文主要解说runtime相关知识, ...

  9. UIViewController相关知识

    title: UIViewController 相关知识date: 2015-12-13 11:50categories: IOS tags: UIViewController 小小程序猿我的博客:h ...

随机推荐

  1. 夺命雷公狗---DEDECMS----1dedecms的安装过程

    我们这次要玩的dedecms(cms也就是内容管理系统),电商网.或者政府网..小说网.新闻网之类的都是基于可以用cms来实现的. 现在在市场上主流的cms系统有dedecms(织梦),帝国cms,p ...

  2. 夺命雷公狗jquery---2层级选择器

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  3. Power Gating的设计(模块)

    Switching Fabric的设计: 三种架构:P沟道的switch vdd(header switch),N沟道的switch vss(footer switch),两个switch. 但是如果 ...

  4. 【crunch bang】论坛tint2配置讨论贴

    地址: http://crunchbang.org/forums/viewtopic.php?id=3232

  5. Angularjs之基本概念梳理(一)

    1.Angularjs指令属性ng-app和ng-controller的理解 ng-app指令-标记了AngularJS脚本的作用域,在<html>中添加ng-app属性即说明整个< ...

  6. mybatis 相关总结

    1. Mybatis的<where><foreach><set>等标签详解:http://blog.csdn.net/zenson_g/article/detail ...

  7. linux设备驱动归纳总结(八):3.设备管理的分层与面向对象思想【转】

    本文转载自:http://blog.chinaunix.net/uid-25014876-id-110738.html linux设备驱动归纳总结(八):3.设备管理的分层与面向对象思想 xxxxxx ...

  8. 【python cookbook】【字符串与文本】14.字符串连接及合并

    问题:将许多小字符串合并成一个大的字符串 解决方案: 1.针对少数量的字符串:+ 2.针对大量的字符串对象的连接,更高效的方法:join() 3.更加复杂的字符串:format() >>& ...

  9. 161109、windows下查看端口占用情况

    1.开始---->运行---->cmd,或者是window+R组合键,调出命令窗口 2.输入命令:netstat -ano,列出所有端口的情况.在列表中我们观察被占用的端口,比如是4915 ...

  10. jQuery的Ajax的跨域请求

    今天碰到一个Ajax跨域请求的问题,我把源码down下来,然后在服务器端写了一个http请求的代理(因为服务器端是不存在跨域问题的),说白了就是用BufferedReader写了个IO流,然后读取到目 ...