class_copyIvarList 之下,没有隐藏的属性

在 Objective-C 中,class_copyIvarList 是一个运行时函数,用于获取指定类的所有实例变量(ivar)的列表。该函数返回一个指向 Ivar 结构体的指针数组,其中每个 Ivar 结构体表示一个实例变量。

函数签名

objc 复制代码
Ivar *class_copyIvarList(Class cls, unsigned int *outCount);

参数

  • cls:需要获取实例变量列表的类。
  • outCount:指向一个无符号整数的指针,用于存储实例变量的数量。

返回值

该函数返回一个指向 Ivar 结构体的指针数组,数组的长度由 outCount 指示。如果类没有实例变量,返回 NULL

示例代码

下面是一个使用 class_copyIvarList 函数的示例,展示如何获取并打印一个类的所有实例变量:

objc 复制代码
#import <Foundation/Foundation.h>
#import <objc/runtime.h>

@interface Person : NSObject {
    NSString *name;
    NSInteger age;
}
@property (nonatomic, strong) NSString *address;
@end

@implementation Person
@end

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        unsigned int count;
        Ivar *ivars = class_copyIvarList([Person class], &count);

        for (unsigned int i = 0; i < count; i++) {
            Ivar ivar = ivars[i];
            const char *name = ivar_getName(ivar);
            const char *type = ivar_getTypeEncoding(ivar);
            NSLog(@"Instance variable name: %s, type: %s", name, type);
        }

        free(ivars);
    }
    return 0;
}

解释

  1. 类定义

    objc 复制代码
    @interface Person : NSObject {
        NSString *name;
        NSInteger age;
    }
    @property (nonatomic, strong) NSString *address;
    @end
    
    @implementation Person
    @end

    定义一个 Person 类,包含两个实例变量 nameage,以及一个属性 address

  2. 获取实例变量列表

    objc 复制代码
    unsigned int count;
    Ivar *ivars = class_copyIvarList([Person class], &count);

    调用 class_copyIvarList 获取 Person 类的实例变量列表,并将数量存储在 count 中。

  3. 遍历实例变量

    objc 复制代码
    for (unsigned int i = 0; i < count; i++) {
        Ivar ivar = ivars[i];
        const char *name = ivar_getName(ivar);
        const char *type = ivar_getTypeEncoding(ivar);
        NSLog(@"Instance variable name: %s, type: %s", name, type);
    }

    遍历 ivars 数组,使用 ivar_getName 获取每个实例变量的名称,使用 ivar_getTypeEncoding 获取类型编码,并打印它们。

  4. 释放内存

    objc 复制代码
    free(ivars);

    调用 free 函数释放由 class_copyIvarList 分配的内存。

输出

执行上述代码后,你将看到类似以下的输出:

复制代码
Instance variable name: name, type: @"NSString"
Instance variable name: age, type: q
Instance variable name: _address, type: @"NSString"

这些输出表示 Person 类的实例变量名称和类型编码,name_addressNSString 类型,ageNSInteger 类型(q 表示 long 类型)。


对 NSMutableArray 执行 class_copyIvarList

NSMutableArray 执行 class_copyIvarList 可以帮助我们了解它的内部实现细节,例如它使用了哪些实例变量来管理数组数据。以下是如何对 NSMutableArray 执行 class_copyIvarList 的示例代码:

objc 复制代码
#import <Foundation/Foundation.h>
#import <objc/runtime.h>

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        // 创建 NSMutableArray 对象
        NSMutableArray *mutableArray = [NSMutableArray arrayWithObjects:@"one", @"two", @"three", nil];
        
        // 获取 NSMutableArray 对象的类
        Class mutableArrayClass = object_getClass(mutableArray);
        
        // 获取类的实例变量列表
        unsigned int count;
        Ivar *ivars = class_copyIvarList(mutableArrayClass, &count);
        
        // 遍历并打印实例变量的名称和类型
        for (unsigned int i = 0; i < count; i++) {
            Ivar ivar = ivars[i];
            const char *name = ivar_getName(ivar);
            const char *type = ivar_getTypeEncoding(ivar);
            NSLog(@"Instance variable name: %s, type: %s", name, type);
        }
        
        // 释放由 class_copyIvarList 分配的内存
        free(ivars);
    }
    return 0;
}

解释

  1. 创建 NSMutableArray 对象

    objc 复制代码
    NSMutableArray *mutableArray = [NSMutableArray arrayWithObjects:@"one", @"two", @"three", nil];

    创建一个包含三个字符串元素的可变数组对象。

  2. 获取 NSMutableArray 对象的类

    objc 复制代码
    Class mutableArrayClass = object_getClass(mutableArray);

    获取 mutableArray 对象的类。

  3. 获取类的实例变量列表

    objc 复制代码
    unsigned int count;
    Ivar *ivars = class_copyIvarList(mutableArrayClass, &count);

    调用 class_copyIvarList 获取 NSMutableArray 类的实例变量列表,并将数量存储在 count 中。

  4. 遍历并打印实例变量的名称和类型

    objc 复制代码
    for (unsigned int i = 0; i < count; i++) {
        Ivar ivar = ivars[i];
        const char *name = ivar_getName(ivar);
        const char *type = ivar_getTypeEncoding(ivar);
        NSLog(@"Instance variable name: %s, type: %s", name, type);
    }

    遍历 ivars 数组,使用 ivar_getName 获取每个实例变量的名称,使用 ivar_getTypeEncoding 获取类型编码,并打印它们。

  5. 释放内存

    objc 复制代码
    free(ivars);

    调用 free 函数释放由 class_copyIvarList 分配的内存。

输出

执行上述代码后,你可能会看到类似以下的输出,具体内容取决于 NSMutableArray 的内部实现(实际输出可能会有所不同):

复制代码
Instance variable name: _storage, type: ^{__CFArray=}
Instance variable name: _mutations, type: I

这些输出表示 NSMutableArray 类的实例变量名称和类型编码,例如 _storage 可能是一个指向内部数组存储的指针,_mutations 是用于跟踪数组修改次数的变量。具体的实例变量名称和类型取决于 NSMutableArray 的内部实现细节。

相关推荐
余生大大3 小时前
关于Safari浏览器在ios<16.3版本不支持正则表达式零宽断言的解决办法
ios·正则表达式·safari
爱分享的程序员4 小时前
前端跨端框架的开发以及IOS和安卓的开发流程和打包上架的详细流程
android·前端·ios
Macle_Chen4 小时前
ios开发中xxx.debug.dylib not found
ios·bug·debug.dylib
WDeLiang19 小时前
Flutter 环境搭建
flutter·ios·visual studio code
lilili啊啊啊1 天前
iOS 应用性能测试工具对比:Xcode Instruments、克魔助手与性能狗
测试工具·ios·iphone·xcode·克魔
264玫瑰资源库2 天前
嘻游电玩三端客户端部署实战:PC + Android + iOS 环境全覆盖教程
android·ios
鸿蒙布道师2 天前
鸿蒙NEXT开发权限工具类(申请授权相关)(ArkTs)
android·ios·华为·harmonyos·arkts·鸿蒙系统·huawei
鸿蒙布道师2 天前
鸿蒙NEXT开发定位工具类 (WGS-84坐标系)(ArkTs)
android·ios·华为·harmonyos·arkts·鸿蒙系统·huawei
ghhgy5312 天前
已安装爱思助手和Apple相关驱动,但仍无法有线连接iPhone热点,且网络适配器没有Apple Mobile Device Ethernet,问题解决
ios·iphone
陈皮话梅糖@2 天前
iOS error: some files could not be transferred (code 23) at xxx
ios