JHHK

欢迎来到我的个人网站
行者常至 为者常成

Runtime(九):类对象信息获取封装

目录

封装

因为是类对象的信息,我们给NSObject添加一个分类

NSObject+classInfo.h

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface NSObject (classInfo)


/// 打印类对象遵守的协议
+(void)printProtocolNames;


/// 打印类对象的成员变量
+ (void)printIvarNames;


/// 打印类对象的属性信息
+ (void)printPropertyNames;



/// 打印实例方法
+ (void)printInstanceMethodNames;


/// 打印类方法
+ (void)printClassMethodNames;


/// 打印所有信息
+(void)printInfoOfClass;

@end
NS_ASSUME_NONNULL_END

NSObject+classInfo.m

#import "NSObject+classInfo.h"
#import <objc/runtime.h>


@implementation NSObject (classInfo)


+(void)printProtocolNames{
    unsigned int count;
    
//    Class cls = object_getClass([[self alloc] init]);
    
    //获得协议列表
    Protocol *__unsafe_unretained * protocolList = class_copyProtocolList(self, &count);
    
    //遍历列表
    for (int i=0; i<count; i++) {
        //获得变量
        const char * names = protocol_getName(protocolList[i]);
        NSLog(@"protocolNames-%d = %s",i,names);
    }
    
    printf("\n");
}



+ (void)printIvarNames{
    unsigned int count;
    //获得成员变量列表
    Ivar * varList = class_copyIvarList(self, &count);
    
    //遍历属性列表
    for (int i=0; i<count; i++) {
        //获得变量
        Ivar var = varList[i];
        //获得变量名
        const char * varName = ivar_getName(var);;
        NSLog(@"varName-%d = %s",i,varName);
    }
    
    printf("\n");
}
    
    
+ (void)printPropertyNames{
    unsigned int count;
    //获得属性列表
    objc_property_t * propertyList = class_copyPropertyList(self, &count);
    
    //遍历属性列表
    for (int i=0; i<count; i++) {
        //获得方法
        objc_property_t property = propertyList[i];
        
        //获得方法名
        const char * propertyName = property_getName(property);
        NSLog(@"propertyName-%d = %s",i,propertyName);
    }
    
    printf("\n");
}


+ (void)printInstanceMethodNames{
    unsigned int count;
    //获得方法列表
    Method * methodList = class_copyMethodList(self, &count);
    
    //遍历方法列表
    for (int i=0; i<count; i++) {
        //获得方法
        Method method = methodList[i];
        
        //获得方法名
        SEL nameSel = method_getName(method);
        NSString * methodName =NSStringFromSelector(nameSel);
        NSLog(@"instanceMethodName-%d = %@",i,methodName);
    }
    
    printf("\n");
}

+ (void)printClassMethodNames{
    unsigned int count;
    Class cls = object_getClass(self);
    //获得方法列表
    Method * methodList = class_copyMethodList(cls, &count);
    
    //遍历方法列表
    for (int i=0; i<count; i++) {
        //获得方法
        Method method = methodList[i];
        
        //获得方法名
        SEL nameSel = method_getName(method);
        NSString * methodName =NSStringFromSelector(nameSel);
        NSLog(@"classMethodName-%d = %@",i,methodName);
    }
    
    printf("\n");
}



+(void)printInfoOfClass{
    NSLog(@"----------- protocol -----------");
    [self printProtocolNames];
    
    NSLog(@"----------- iVar -----------");
    [self printIvarNames];
    
    NSLog(@"----------- property -----------");
    [self printPropertyNames];
    
    NSLog(@"----------- instanceMethod -----------");
    [self printInstanceMethodNames];
    
    NSLog(@"----------- classMethod -----------");
    [self printClassMethodNames];
}

@end

调用

我们来验证下

创建一个Person类,如下

Person.h

#import <Foundation/Foundation.h>

@class Person;
NS_ASSUME_NONNULL_BEGIN
@interface Person : NSObject;
@end

NS_ASSUME_NONNULL_END

Person.m

#import "Person.h"

@interface Person()<NSObject>
{
    int _idNumber;
}
@property (nonatomic, assign) BOOL sexy;
@end

@implementation Person

-(void)personInstanceFunTest{}

+(void)personClassFunTest{}

@end

调用试试

#import "Person.h"
#import "NSObject+classInfo.h"
[Person printInfoOfClass];

打印信息如下

2020-01-14 15:20:44.688 iOSTest[12294:2194284] ----------- protocol -----------
2020-01-14 15:20:44.688 iOSTest[12294:2194284] protocolNames-0 = NSObject

2020-01-14 15:20:44.688 iOSTest[12294:2194284] ----------- iVar -----------
2020-01-14 15:20:44.688 iOSTest[12294:2194284] varName-0 = _idNumber
2020-01-14 15:20:44.688 iOSTest[12294:2194284] varName-1 = _sexy

2020-01-14 15:20:44.689 iOSTest[12294:2194284] ----------- property -----------
2020-01-14 15:20:44.689 iOSTest[12294:2194284] propertyName-0 = sexy
2020-01-14 15:20:44.689 iOSTest[12294:2194284] propertyName-1 = hash
2020-01-14 15:20:44.689 iOSTest[12294:2194284] propertyName-2 = superclass
2020-01-14 15:20:44.689 iOSTest[12294:2194284] propertyName-3 = description
2020-01-14 15:20:44.689 iOSTest[12294:2194284] propertyName-4 = debugDescription

2020-01-14 15:20:44.689 iOSTest[12294:2194284] ----------- instanceMethod -----------
2020-01-14 15:20:44.690 iOSTest[12294:2194284] instanceMethodName-0 = personInstanceFunTest
2020-01-14 15:20:44.691 iOSTest[12294:2194284] instanceMethodName-1 = sexy
2020-01-14 15:20:44.691 iOSTest[12294:2194284] instanceMethodName-2 = setSexy:

2020-01-14 15:20:44.691 iOSTest[12294:2194284] ----------- classMethod -----------
2020-01-14 15:20:44.691 iOSTest[12294:2194284] classMethodName-0 = personClassFunTest

行者常至,为者常成!





R
Valine - A simple comment system based on Leancloud.