key-value初始化instanceVariable

接上一篇来介绍下,如何用key-value的形式初始化成员变量

背景接上篇,就不在赘述,如果不了解映射规则的话,可以先看看上一篇
key-value初始化property;

有个上一篇的铺垫,这篇将很好被接受,首先我们通过如下方法实例变量的名称获取到实例变量的指针objc_ivar *Ivar;

Ivar instanceVariable = class_getClassVariable([self class], variableName.UTF8String);

同样Ivar类型为一个系统类型,我们不知道其内部实现,当然apple也同样为我们提供了方法来处理它,和上篇一样,先对处理它的方法做个描述

OBJC_EXPORT Ivar class_getClassVariable(Class cls, const char *name) 
     __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);

OBJC_EXPORT Ivar class_getInstanceVariable(Class cls, const char *name)
    __OSX_AVAILABLE_STARTING(__MAC_10_0, __IPHONE_2_0);

OBJC_EXPORT size_t class_getInstanceSize(Class cls) 
     __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);

OBJC_EXPORT Ivar *class_copyIvarList(Class cls, unsigned int *outCount) 
     __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);

OBJC_EXPORT void object_setIvar(id obj, Ivar ivar, id value) 
     __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);

OBJC_EXPORT Ivar object_setInstanceVariable(id obj, const char *name, void *value)
    __OSX_AVAILABLE_STARTING(__MAC_10_0, __IPHONE_2_0)
    OBJC_ARC_UNAVAILABLE;

OBJC_EXPORT id object_getIvar(id obj, Ivar ivar) 
     __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);

这里我们要用到的就是class_getInstanceVariable方法、class_getClassVariable方法 、object_setIvar方法

步骤

  1. 获取成(类)员变量的指针Ivar instanceVariable
  2. object_setIvar初始化
注意,如果是以字符串的形式传递参数,请在setIvar方法之前转换成合适的类型

实现可参加下面代码

- (void)setIvarWithVariable : (id)variable VariableName : (NSString *)variableName
{
    Ivar instanceVariable = class_getClassVariable([self class], variableName.UTF8String);
    if (instanceVariable) {
        NSString *type = [NSString stringWithUTF8String:ivar_getTypeEncoding(instanceVariable)];
        if ([type isEqualToString:@"c"]) {
            object_setIvar(self, instanceVariable, variableName);
        }else if ([type isEqualToString:@"i"]){
            object_setIvar(self, (__bridge Ivar)(@([variable intValue])), variableName);
        }else if ([type isEqualToString:@"s"]){
            object_setIvar(self, (__bridge Ivar)(@([variable shortValue])), variableName);
        }else if ([type isEqualToString:@"l"]){
            object_setIvar(self, (__bridge Ivar)(@([variable longValue])), variableName);
        }else if ([type isEqualToString:@"q"]){
            object_setIvar(self, (__bridge Ivar)(@([variable longLongValue])), variableName);
        }else if ([type isEqualToString:@"C"]){
            object_setIvar(self, (__bridge Ivar)(@([variable integerValue])), variableName);
        }else if ([type isEqualToString:@"S"]){
            object_setIvar(self, (__bridge Ivar)(@([variable unsignedShortValue])), variableName);
        }else if ([type isEqualToString:@"L"]){
            object_setIvar(self, (__bridge Ivar)(@([variable unsignedLongValue])), variableName);
        }else if ([type isEqualToString:@"Q"]){
            object_setIvar(self, (__bridge Ivar)(@([variable unsignedLongLongValue])), variableName);
        }else if ([type isEqualToString:@"f"]){
            object_setIvar(self, (__bridge Ivar)(@([variable floatValue])), variableName);
        }else if ([type isEqualToString:@"d"]){
            object_setIvar(self, (__bridge Ivar)(@([variable doubleValue])), variableName);
        }else if ([type isEqualToString:@"B"]){
            object_setIvar(self, (__bridge Ivar)(@([variable boolValue])), variableName);
        }else{
            object_setIvar(self, (__bridge Ivar)(variable), variableName);
        }
    }
}

关于类型定义的一些说明

关于类型定义的一些说明

需要注意的是,oc中不支持long double类型,所以当double类型对待

本文遵守 CC-BY-NC-4.0 许可协议。

Creative Commons License

欢迎转载,转载需注明出处,且禁止用于商业目的。

上篇资源定位-页面管理器
下篇key-value初始化property