iOS开发之RunTime上手入门

     众所周知,Objective-C是iOS开发的第一语言(虽然最近两年Swift发展迅猛,在最近的TIOBE编程语言排行榜上Swift的排名已经超过了Objective-C,但是现在iOS主流应用依然还是用Objective-C完成的)。Objective-C有一个可以称之为杀手级的语言特征—-动态性,而OC的动态性最主要依赖的就是运行时系统(RunTime)。

      很多人在刚接触OC的运行时系统(RunTime)时,觉得它很深奥,因为它用到了C语言的API,毕竟很多的iOS程序员的C语言水平并不是很强,甚至到了看到C语言就恐惧的地步。因此在这里我通过几个简单的案例来阐述RunTime机制的强大之处,算是一个小小的入门了。

      1-最简单的运行时系统应用:根据字符串来调用内存中的一个类。

      这是运行时机制最常见也是最简单的应用了,它简单到甚至不用在项目中写入#import 

<objc/runtime.h>用来导入runtime库。它根据传入的字符串来获取内存中存在的类。

其代码如下:

//1-根据字符串返回一个类

Class cls =NSClassFromString(@”Person”);

//2-根据类来创建对象

id person = [[cls alloc]init];

//3-给person的属性赋值

[person performSelector:@selector(setName:)withObject:@”wang”];

//4-返回person的name属性值(使用KVC返回属性值)

NSLog(@”person的name是%@”,[person valueForKey:@”name”]);

//5-调用person的eat方法

if([person respondsToSelector:@selector(Eat)])

{

[person performSelector:@selector(Eat)withObject:nil];

}

else

{

NSLog(@”person不存在的方法”);

}

   2- 在程序运行时动态地添加一个类

     当需要在程序运行时动态地添加一个新的类到内存中时,我们需要用到C语言的API,需要导入runtime库,此时动态生成的类就会存在于内存中。

代码如下:

#import <objc/runtime.h>

//1-设置类名(类名是常量)

const char*className =”Dog”;

//2-根据类名获取类

Class cls =objc_getClass(className);

//3-判断类存不存在

if(!cls)

{

//4-如果类不存在于当前的内存下,则需要重新根据类名来创建这个类

//4-1设置运行时类的父类

Class superClass = [NSObject class];

//4-2在运行时下创建类

cls =objc_allocateClassPair(superClass, className, 0);

//5-判断类存不存在

if(!cls)

{

NSLog(@”Dog类不存在”);

return;

}

else

{

//此时动态创建的Dog类存在于内存中

NSLog(@”Dog类存在”);

}

//6-在内存中注册类!!!!

#warning在内存中注册类,一定要加!!!!!

objc_registerClassPair(cls);

}

else

{

//类存在说明在当前的内存中已经存在了这个类(包括一些UIKit的系统类等)

NSLog(@”类已经存在”);

}

    通过代码可以看出来,一股浓浓的C语言代码风格袭来,在内存中根据类名获取类还有在运行时创建一个新的类都用到了C语言的函数。

     3- 运行时给内存中的类添加新的方法

     此时也需要添加C语言的API,需要导入runtime库,代码如下:

-(void)RunTime3withClassName:(NSString*) className

{

//1-获取内存中相关的类

Class cls =NSClassFromString(className);

if(!cls)

{

NSLog(@”%@类不存在”,className);

return;

}

else

{

NSLog(@”%@类存在”,className);

}

//2-添加方法的实现(使用block实现,在block内传入方法参数)

IMP myImp =imp_implementationWithBlock(^(id_self,NSString*str){

NSLog(@”Hello %@”,str);

});

class_addMethod(cls,@selector(sayHello:), myImp,”v@:@”);

//3-判断有没有添加方法成功

id person = [[cls alloc]init];

if([person respondsToSelector:@selector(sayHello:)])

{

[person performSelector:@selector(sayHello:)withObject:@”World”];

}

else

{

NSLog(@”当前的方法不存在”);

}

}

    原文作者:jiongjiongwang
    原文地址: https://www.jianshu.com/p/c86262730c25
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞