iOS runtime(一)

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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值