Objective-C中runtime机制的应用(一)

简介: Objective-C中runtime机制的应用

Objective-C中runtime机制的应用


一、初识runtime


       Objective-C是一种动态语言,所谓动态语言,是在程序执行时动态的确定变量类型,执行变量类型对应的方法的。因此,在Object-C中常用字符串映射类的技巧来动态创建类对象。因为OC的动态语言特性,我们可以通过一些手段,在程序运行时动态的更改对象的变量甚至方法,这就是我们所说的runtime机制。


二、你还有什么办法操作这样的变量么?


       首先,我们先来看一个例子,这里有我创建的一个MyObject类:


//.h===========================

@interface MyObject : NSObject

{

   @private

   int privateOne;

   NSString * privateTow;;

}

@end

//=============================

//.m===========================

@interface MyObject()

{

   @private

   NSString * privateThree;

}

@end

@implementation MyObject

- (instancetype)init

{

   self = [super init];

   if (self) {

       privateOne=1;

       privateTow=@"Tow";

       privateThree=@"Three";

   }

   return self;

}

-(NSString *)description{

   return [NSString stringWithFormat:@"one=%d\ntow=%@\nthree=%@\n",privateOne,privateTow,privateThree];

}

@end

//=============================


这个类是相当的安全,首先,在头文件中没有提供任何的方法接口,我们没有办法使用点语法做任何操作,privateOne和PrivateTow两个变量虽然声明在了头文件中,却是私有类型的,通过指针的方式我们虽然可以看到他们,却不能做任何读取修改的操作,xcode中的提示如下:


image.png





他会告诉我们,这是一个私有的变量,我们不能使用。对于privateThree,我们更是束手无策,不仅不能使用,我们甚至都看不到它的存在。那么对于这种情况,你有什么办法操作这些变量么?对,是时候展现真正的技术了:runtime!


三、通过runtime获取对象的变量列表


       要操作对象的变量,我们首先应该要捕获这些变量,让他们无处遁形。无论声明在头文件或是实现文件,无论类型是公开的还是私有的,只要声明了这个变量,系统就会为其分配空间,我们就可以通过runtime机制捕获到它,代码如下:


#import "ViewController.h"

#import "MyObject.h"

//包含runtime头文件

#import <objc/runtime.h>

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {

   [super viewDidLoad];

   //我们先声明一个unsigned int型的指针,并为其分配内存

   unsigned int * count = malloc(sizeof(unsigned int));

   //调用runtime的方法

   //Ivar:方法返回的对象内容对象,这里将返回一个Ivar类型的指针

   //class_copyIvarList方法可以捕获到类的所有变量,将变量的数量存在一个unsigned int的指针中

   Ivar * mem = class_copyIvarList([MyObject class], count);

   //进行遍历

   for (int i=0; i< *count ; i++) {

       //通过移动指针进行遍历

       Ivar var = * (mem+i);

       //获取变量的名称

       const char * name = ivar_getName(var);

       //获取变量的类型

       const char * type = ivar_getTypeEncoding(var);

       NSLog(@"%s:%s\n",name,type);

   }

   //释放内存

   free(count);

   //注意处理野指针

   count=nil;

}

- (void)didReceiveMemoryWarning {

   [super didReceiveMemoryWarning];

   // Dispose of any resources that can be recreated.

}


@end


打印结果如下,其中i表示int型:


image.png


是不是小吃惊了一下,无论变量在哪里,只要它在,就让它无处遁形。


四、让我找到你,就让我改变你!


       仅仅能够获得变量的类型和名字或许并没有什么卵用,没错,我们获取变量的目的不是为了观赏,而是为了操作它,这对runtime来说,也是小事一碟。代码如下:


- (void)viewDidLoad {

   [super viewDidLoad];

   //获取变量

   unsigned int  count;

   Ivar * mem = class_copyIvarList([MyObject class],&count);

   //创建对象

   MyObject * obj = [[MyObject alloc]init];

   NSLog(@"before runtime operate:%@",obj);

   //进行变量的设置

   object_setIvar(obj, mem[0],10);

   object_setIvar(obj, mem[1], @"isTow");

   object_setIvar(obj, mem[2], @"isThree");

   NSLog(@"after runtime operate:%@",obj);

 

}


Tip:在修改int型变量的时候,你或许会遇到一个问题,ARC下,编译器不允许你将int类型的值赋值给id,在buildset中将Objective-C Automatic Reference Counting修改为No即可。


打印效果如下:


image.png


可以看到,那些看似非常安全的变量被我们修改了。

目录
相关文章
|
存储 安全 API
Objective-C Runtime 基本使用
在上一篇文章Objective-C Runtime详解 中我们探讨了Runtime的基本原理,这篇文章我们将总结一下Runtime的一些基本使用
173 0
|
存储 缓存 算法
Objective-C Runtime 详解
最近在学习Runtime的知识,恰巧发现了这篇博客[《Objective-C Runtime》](http://yulingtianxia.com/blog/2014/11/05/objective-c-runtime/),在此基础上,进行了些许补充说明,如有错误或其他想法,欢迎提出交流。
131 0
|
安全 编译器 API
属性“__attribute__”在Objective-C中的应用
属性“__attribute__”在Objective-C中的应用
225 0
属性“__attribute__”在Objective-C中的应用
|
iOS开发
动态的Objective-C——关于消息机制与运行时的探讨(三)
动态的Objective-C——关于消息机制与运行时的探讨
211 0
动态的Objective-C——关于消息机制与运行时的探讨(三)
|
iOS开发 开发者
动态的Objective-C——关于消息机制与运行时的探讨(二)
动态的Objective-C——关于消息机制与运行时的探讨
167 0
动态的Objective-C——关于消息机制与运行时的探讨(二)
|
缓存 自然语言处理 IDE
动态的Objective-C——关于消息机制与运行时的探讨(一)
动态的Objective-C——关于消息机制与运行时的探讨
173 0
动态的Objective-C——关于消息机制与运行时的探讨(一)
|
程序员 编译器 C#
Objective-C中runtime机制的应用(二)
Objective-C中runtime机制的应用
117 0
Objective-C中runtime机制的应用(二)
|
iOS开发 开发者
动态的Objective-C——关于消息机制与运行时的探讨(四)
动态的Objective-C——关于消息机制与运行时的探讨
138 0
|
存储 C语言 iOS开发
(转载)Objective-C总Runtime的那点事儿(一)消息机制
原文地址:http://www.cocoachina.com/ios/20141018/9960.html 找工作,Objective-C中的Runtime是经常被问到的一个问题,几乎是面试大公司必问的一个问题。
989 0