一、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. 夺命雷公狗---node.js---22之项目的构建在node+express+mongo的博客项目7之数据的修改

    在修改的时候和在PHP里面修改的一样,都是需要在列表页传个id过来才可以实现修改的,如下所示: 然后在后端接收到他传过来id的同时去读取该id的所有信息: 然后就开始写post处理数据方面的问题了,如 ...

  2. 亚马逊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 ...

  3. rqnoj-342-最不听话的机器人-dp

    dp[i][j][k][[l]: 执行第i步,执行到点(j,k),方向为l时,用的最大步数. 状态转移根据step[i]转移. #include<stdio.h> #include< ...

  4. android 项目学习随笔二十(屏幕适配)

    1.图片适配 放入相同名称的资源文件,机器根据不同分辨率找相近的资源 240*320 ldpi 320*480 mdpi 480*800 hdpi 720*1280 xhdpi 2.布局适配 在不同的 ...

  5. 鸟哥的linux私房菜之vim

    vim是vi的进阶版本

  6. linux设备驱动归纳总结(三):7.异步通知fasync【转】

    本文转载自:http://blog.chinaunix.net/uid-25014876-id-62725.html linux设备驱动归纳总结(三):7.异步通知fasync xxxxxxxxxxx ...

  7. java几道简单的面试题目

    1.   请问以下程序会输出什么? public   class   Test   {  public   static   void   main(String[]   args)   {  Par ...

  8. html插入视频

    http://www.jb51.net/web/168548.html http://www.w3school.com.cn/html/html_media.asp

  9. rtc关机闹钟7 jni层 com_android_server_AlarmManagerService

    frameworks/base/services/core/jni/com_android_server_AlarmManagerService.cpp int AlarmImplAlarmDrive ...

  10. Javascript中自动切换焦点

      <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title&g ...