设为首页 加入收藏

TOP

Runtime的几个小例子(含Demo)(一)
2017-10-13 10:32:58 】 浏览:4633
Tags:Runtime 例子 Demo

一、什么是runtime(也就是所谓的“运行时”,因为是在运行时实现的。) 

          1.runtime是一套底层的c语言API(包括很多强大实用的c语言类型,c语言函数);  [runtime运行系统]  

        2.实际上,平时我们编写的oc代码,底层都是基于runtime实现的;                             [OC语言的动态性] 

 运行时系统 (runtime system),对于C语言,函数的调用在编译的时候会决定调用哪个函数。对于OC的函数,属于动态调用过程,在编译的时候并不能决定真正调用哪个函数,只有在真正运行的时候才会根据函数的名称找到对应的函数来调用。 runtime就是OC辛苦的幕后工作人员。(编译器会自动帮助我们编译成runtime代码。

动态特性,使得它在语言层面上支持程序的可扩展性。只有在程序运行时,才会去确定对象的类型,并调用类与对象相应的方法。利用runtime机制让我们可以在程序运行时动态修改类的具体实现、包括类中的所有私有属性、方法。这也是本文runtime例子的出发点。

我们所敲入的代码转化为运行时的runtime函数代码,最终在程序运行时转成了底层的runtimec语言代码 ;

举例:

当某个对象使用语法[receiver message]来调用某个方法时,其实[receiver message]被编译器转化为:

id objc_msgSend ( id self, SEL op, ... );  

也就是说,我们平时编写的oc代码,方法调用的本质,就是在编译阶段,编译器转化为向对象发送消息。

本次开发环境: Xcode:7.2     iOS Simulator:iphone6   By:啊左     本文Demo下载链接:runtime-Demo

 

二、runtime的几种使用方法

我们通过继承于NSObject的person类,来对runtime进行学习。

本文共有6个关于runtime机制方法的小例子,分别是:

  1. 获取person类的所有变量;
  2. 获取person类的所有方法;
  3. 改变person类的私有变量name的值;
  4. 为person的category类增加一个新属性;
  5. person类添加一个方法;
  6. 交换person类的2个方法的功能;

(个人习惯,喜欢为6个例子添加按钮各自的行为方法,并分别执行相应的行为,以此看清各个runtime函数的具体功能所带来的效果。)

 

首先,创建新的项目,并在项目中新建一个普通的OC类:person类(继承于NSObject),为了避免后面与其他方法函数搞混,我们把完整的person类编写齐全,用于后面使用runtime的几种方法:

①person.h如下:

#import <Foundation/Foundation.h>
@interface person : NSObject
@property (nonatomic,assign)
int age; //属性变量 -(void)func1; -(void)func2; @end

②person.m如下:

#import "person.h"

@implementation person { NSString *name; //实例变量 }//初始化person属性
-(instancetype)init { self = [super init]; if(self) { name = @"Tom"; self.age = 12; } return self; } //person的2个普通方法
-(void)func1 { NSLog(@"执行func1方法。"); } -(void)func2 { NSLog(@"执行func2方法。"); } //输出person对象时的方法:
-(NSString *)description { return [NSString stringWithFormat:@"name:%@ age:%d",name,self.age]; } @end

从person类的描述中,我们可以看到person类含有一个可供外类使用的共有属性age,以及一个外界不可以访问私有属性name,但是,有木有想过,其实在外类,name也是可以访问的。OC里面,通过runtime系统,苹果允许不受这些私有属性的限制,对私有属性私有方法等进行访问、添加、修改、甚至替换系统的方法。

那么,为项目的故事板添加6个按钮;

在使用runtime的地方,我们都需要包含头文件:    (本文几个例子中,都只需要在ViewController.m中包含.)

#import <objc/runtime.h>

 

1.获取person类的所有变量

将第一个按钮关联到ViewController.h,添加行为并命名其方法为:“getAllVariable”:

- (IBAction)getAllVariable:(UIButton *)sender;   //获取所有变量

在ViewController.m中的实现如下:

/*1.获取person所有的成员变量*/
- (IBAction)getAllVariable:(UIButton *)sender {
unsigned
int count = 0; //获取类的一个包含所有变量的列表,IVar是runtime声明的一个宏,是实例变量的意思. Ivar *allVariables = class_copyIvarList([person class], &count); for(int i = 0;i<count;i++) { //遍历每一个变量,包括名称和类型(此处没有星号"*") Ivar ivar = allVariables[i]; const char *Variablename = ivar_getName(ivar); //获取成员变量名称 const char *VariableType = ivar_getTypeEncoding(ivar); //获取成员变量类型 NSLog(@"(Name: %s) ----- (Type:%s)",Variablename,VariableType); } }

点击按钮后,得到的输出如下:(i表示类型为int)

2016-05-18 17:17:10.502 runtime运行时[10164:452725] (Name: name) ----- (Type:@"NSString") 2016-05-18 17:17:10.503 runtime运行时[10164:452725] (Name: _age) ----- (Type:i) 

分析Ivar,一个指向objc_ivar结

首页 上一页 1 2 3 4 下一页 尾页 1/4/4
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇iOS UIScrollView的使用 下一篇iOS开发UI篇-tableView在编辑状态..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目