iOS开发Runtime那点事

runtime介绍

runtime从字面上的意思理解就是运行时间,run(跑,运行)time(时间),在iOS中呢俗称运行时,它是一套底层的纯C语言API,属于一个C语言库,包含了很多底层的C语言API,同时它也是OC的幕后工作者,我们平时写的OC代码在运行的过程中都会转为runtime的C语言代码。

runtime的作用

注意哦:用到runtime的地方要导入头文件:objc/runtime.h

作用1:获取一个类全部的成员变量名(私有成员变量也可以获取到滴哦)

我们新建一个Person类,.h代码如下:


#import <Foundation/Foundation.h>

/**
 *  Person类协议
 */
@protocol PersonDelegate <NSObject>

- (void) PersonDelegateToWork;

@end


@interface Person : NSObject

#pragma mark - 属性

@property (nonatomic,strong) NSString *name;    //姓名

@property (nonatomic,strong) NSString *sex;     //性别

@property (nonatomic,assign) NSInteger age;     //年龄


#pragma mark - 方法

- (void) eat;

- (void) work;

- (void) sleep;

@end

这些成员变量都是共有的,同时在.m文件中我们添加私有属性NSString *job,下面看测试代码:

/**
 *  获取一个类的全部成员变量
 */
- (void) getObjcAllIvars{

    unsigned int count = 0;

    //获取成员变量的结构体
    Ivar *ivars = class_copyIvarList([Person class], &count);

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

        //获取成员变量的名称,获取到的都为C字符串
        const char *name = ivar_getName(ivars[i]);

        //C字符串专为OC字符串
        NSString *OC_name = [NSString stringWithUTF8String:name];

        NSLog(@"i:%d ---- name:%@",i,OC_name);

    }

    //因为ivars不属于OC对象,所以要记得释放
    free(ivars);
}

打印结果:

这里写图片描述

如上我们看到结果中不仅打印出了公有成员变量,同时私有成员变量也打印了出来。

作用2 同理,我们可以获取到一个类的全部属性名

/**
 *  获取一个类的全部属性名称
 */
- (void) getObjcAllProperties{

    unsigned int count = 0;

    objc_property_t *properties = class_copyPropertyList([Person class], &count);

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

        //获取属性名称(C字符串)
        const char *name = property_getName(properties[i]);

        NSString *OC_name = [NSString stringWithUTF8String:name];

        NSLog(@"i:%d --- propertyName:%@",i,OC_name);

    }

    //非OC对象,记得释放
    free(properties);

}

打印结果:

这里写图片描述

作用3 获取一个类的全部方法

/**
 *  获取一个类的全部方法
 */
- (void) getObjcAllMethod{

    unsigned int count = 0;

    //获取指向改类所有方法的指针
    Method *methods = class_copyMethodList([Person class], &count);

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

        //获取方法
        SEL method = method_getName(methods[i]);

        //获取方法名字(C字符串)
        const char *name = sel_getName(method);

        NSString *methodName = [NSString stringWithUTF8String:name];

        //获取方法参数个数
        int arguments = method_getNumberOfArguments(methods[i]);

        NSLog(@"i:%d ---- methodName:%@ --- arguments:%d",i,methodName,arguments);
    }
    //释放
    free(methods);
}

打印结果:

这里写图片描述

作用4 获取一个类遵循的所有协议

使当前viewcontroller遵守Person类的协议

这里写图片描述

/**
 *  获取一个类遵循的全部协议
 */
- (void) getObjcAllProtocol{

    unsigned int count = 0;

    //获取指向改类遵循的所有协议的指针
    __unsafe_unretained Protocol **protocols = class_copyProtocolList([self class], &count);

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

        //获取改类遵循的一个协议指针
        Protocol *protocol = protocols[i];

        //获取C字符串协议名字
        const char *name = protocol_getName(protocol);

        NSString *OCProtocolName =[NSString stringWithUTF8String:name];

        NSLog(@"i:%d --- protocolName:%@",i ,OCProtocolName);
    }

    //释放
    free(protocols);

}

打印结果:

这里写图片描述

作用5 利用runtime 归档解档

-(void)encodeWithCoder:(NSCoder *)aCoder{

    unsigned int count = 0;

    //获得指向当前类的一个属性的指针
    objc_property_t *properties = class_copyPropertyList([self class], &count);

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

        //获取指向当前类的一个属性的指针
        objc_property_t property = properties[i];

        //获取C字符串属性名
        const char *name = property_getName(property);

        NSString *propertyName = [NSString stringWithUTF8String:name];

        NSString *propertyValue = [self valueForKey:propertyName];

        //编码属性
        [aCoder encodeObject:propertyValue forKey:propertyName];
    }

    //记得释放
    free(properties);
}

-(instancetype)initWithCoder:(NSCoder *)aDecoder{

    unsigned int count = 0;

    //获取指向当前类的所有属性的指针
    objc_property_t *properties = class_copyPropertyList([self class], &count);

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

        //获取指向当前类的一个属性的指针
        objc_property_t property = properties[i];

        const char *name = property_getName(property);

        NSString *propertyName = [NSString stringWithUTF8String:name];

        //解码属性值
        NSString *propertyValue = [aDecoder decodeObjectForKey:propertyName];

        [self setValue:propertyValue forKey:propertyName];

    }

    //释放
    free(properties);

    return self;
}
/**
 *  归档/解档
 */
- (void) deCode{

    Person *person = [[Person alloc] init];

    person.name = @"王五";
    person.sex = @"男";
    person.age = 20;

    NSString *path = [NSString stringWithFormat:@"%@/archive",NSHomeDirectory()];

    [NSKeyedArchiver archiveRootObject:person toFile:path];

    Person *unarchivePerson = [NSKeyedUnarchiver unarchiveObjectWithFile:path];

    NSLog(@"unarchivePerson:%@",unarchivePerson);

}

打印结果:
这里写图片描述

其实runtime的作用有太多太多了,今天就先给大家分享到这了。

源码请戳这里runtime简单使用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值