成员变量Ivar

通过Ivar可以,获取类所有的成员变量。

1.1 Ivar 的类型

一个objc_ivar *指针

/// An opaque type that represents an instance variable.
typedef struct objc_ivar *Ivar;

objc_ivar的结构:

struct objc_ivar {
    char * _Nullable ivar_name      OBJC2_UNAVAILABLE;
    char * _Nullable ivar_type      OBJC2_UNAVAILABLE;
    int ivar_offset                 OBJC2_UNAVAILABLE;
#ifdef __LP64__
    int space                       OBJC2_UNAVAILABLE;
#endif
}                                   OBJC2_UNAVAILABLE;

ivar_name:变量名 ,如: _age 、 _name...
ivar_type: 变量的属性 ,表示int 、short 、NSString...
ivar_offset: 偏移量,变量在实例对象中的偏移量
space: 不清楚,64位机上才有

注意:OBJC2_UNAVAILABLE,表示Objective-C 2 中不可用。

这里的不可用,是指无法直接使用。
ivar_name 、ivar_type 、ivar_offset apple提供方法获取
space 没有找到获取的方法

1.2 Ivar 常用方法

下面是有关Ivar的常用方法

// 获取类的所有成员变量
Ivar *class_copyIvarList(Class cls, unsigned int * outCount);

// 通过变量名称获取类中的成员变量
Ivar class_getInstanceVariable(Class cls, const char *name);

// 获取Ivar的ivar_name
const char *ivar_getName(Ivar v);

// 获取Ivar的ivar_type
const char *ivar_getTypeEncoding(Ivar v);

// 获取Ivar的ivar_offset
ptrdiff_t ivar_getOffset(Ivar v);

// 设置实例对象中Ivar的值
void object_setIvar(id obj, Ivar ivar, id value);

// 获取实例对象中Ivar的值
id object_getIvar(id obj, Ivar ivar);
                                                 

1.3 Ivar 查看类的所有成员变量


void showIvarList(Class cls){
    unsigned int count;
    Ivar *ivars = class_copyIvarList(cls,&count);
    for (int i = 0; i < count; i++) {
        Ivar ivar = ivars[i];
        const char *ivar_name = ivar_getName(ivar);
        const char *ivar_type = ivar_getTypeEncoding(ivar);
        ptrdiff_t ivar_offset = ivar_getOffset(ivar);
        NSLog(@"name:%s type:%s offset:%td",ivar_name,ivar_type,ivar_offset);
    }
    // 需要手动释放
    free(ivars);
}
    

类忽略,结果如下:

name:_sex type:s offset:8
name:_age type:s offset:10
name:_name type:@"NSString" offset:16

type类型含义:

type Meaning
s A short
@ An object (whether statically typed or typed id)

type 类型完整介绍在这里

推荐阅读更多精彩内容