iOS runtime(一)

来源:互联网 发布:期货投资分析 知乎 编辑:程序博客网 时间:2024/05/20 07:34

runtime,直译的意思就是运行时,这是iOS开发中很重要的一个概念,其本质就是消息发送机制,是iOS开发中的一个黑魔法。众所周知,OC在编译阶段,不管是否有实现这个方法,都可通过编译,这就给开发者留下了很大的空间,可以利用黑魔法,在函数执行的时候动态做一些事情。下面就是我学习runtime的一点记录。

本文介绍runtime的常用方法,包括动态获取一个对象的成员变量、属性、方法以及遵守的协议。下面是实例代码。

使用runtime需要引入头文件"objc/runtime.h"

#import <Foundation/Foundation.h>#import "ProtocolModel.h"@interface Person : NSObject<ProtocalA,ProtocalB>@property (nonatomic,strong) NSString *name;@property (nonatomic,assign) NSInteger age;-(NSString *) getName;-(NSInteger) getAge;+(void) testMethod;@end

#import "Person.h"@implementation Person-(NSString *) getName{    return @"I am Lilei";}-(NSInteger) getAge{    return 25;}+(void) testMethod{    NSLog(@"This is a test class method");}-(NSString *)personDescribe{    return [NSString stringWithFormat:@"name=%@,age=%ld",_name,_age];}@end

#import <Foundation/Foundation.h>@protocol ProtocalA <NSObject>-(void) showA;@end@protocol ProtocalB <NSObject>-(void) showB;@end@interface ProtocolModel : NSObject@end
- (void)viewDidLoad {    [super viewDidLoad];    // Do any additional setup after loading the view, typically from a nib.        Person *person = [[Person alloc] init];        unsigned int count;    NSLog(@"+++++++++++++ 获取属性列表 +++++++++++++");    objc_property_t *propertyList = class_copyPropertyList([person class], &count);    for (unsigned int i = 0; i < count; i ++) {        const char *propertyName = property_getName(propertyList[i]);        NSLog(@"属性:%s",propertyName);    }        NSLog(@"+++++++++++++ 获取方法列表 +++++++++++++");    Method *methodList = class_copyMethodList([person class], &count);    for (unsigned int i = 0; i < count; i ++) {        SEL methodName = method_getName(methodList[i]);        NSLog(@"方法:%@",NSStringFromSelector(methodName));    }        NSLog(@"+++++++++++++ 获取成员变量列表 +++++++++++++");    Ivar *ivarList = class_copyIvarList([person class], &count);    for (unsigned int i = 0; i < count; i ++) {        const char *ivarName = ivar_getName(ivarList[i]);        NSLog(@"成员变量:%s",ivarName);                if(0 == i)        {            object_setIvar(person, ivarList[i], @"Han Meimei");        }        if(1 == i)        {            //此处修改NSInteger类型属性失败,有知道方法的可以评论告诉我            object_setIvar(person, ivarList[i], @23);        }    }    NSLog(@"动态变量控制:name = %@",person.name);    NSLog(@"动态变量控制:age = %ld",person.age);        NSLog(@"+++++++++++++ 获取协议列表 +++++++++++++");    __unsafe_unretained Protocol **protocolList = class_copyProtocolList([person class], &count);    for (unsigned int i = 0; i < count; i ++) {        const char *protocolName = protocol_getName(protocolList[i]);        NSLog(@"协议名:%s",protocolName);    }        //通过方法名获得类方法    Class personClass = object_getClass([Person class]);    SEL classSel = @selector(testMethod);    Method classMethod = class_getInstanceMethod(personClass, classSel);        //通过方法名获得实例方法    SEL objSel1 = @selector(getName);    Method objMethod1 = class_getInstanceMethod([person class], objSel1);        SEL objSel2 = @selector(getAge);    Method objMethod2 = class_getInstanceMethod([person class], objSel2);        //交换两个方法的实现    NSLog(@"交换前-------%@,%ld",[person getName],[person getAge]);    //由于方法的返回类型不一致,程序运行到此处会失败,这里只是介绍使用方法    method_exchangeImplementations(objMethod1, objMethod2);    NSLog(@"交换后-------%@,%ld",[person getName],[person getAge]);}



0 0
原创粉丝点击