如果 object_getIvar 中的变量是基本数据类型(例如,float、int、bool),当函数根据文档返回指针(id)时,我如何获取该值。我尝试转换为 int, int* 但是当我尝试将其转换为 NSLog 时,我收到有关不兼容指针类型的错误。
5 回答
得到:
myFloat = 2.34f;
float myFloatValue;
object_getInstanceVariable(self, "myFloat", (void*)&myFloatValue);
NSLog(@"%f", myFloatValue);
输出:
2.340000
设置:
float newValue = 2.34f;
unsigned int addr = (unsigned int)&newValue;
object_setInstanceVariable(self, "myFloat", *(float**)addr);
NSLog(@"%f", myFloat);
输出:
2.340000
对于 ARC:
受此答案的启发:object_getIvar 无法读取 BOOL iVar 的值。您必须对 object_getIvar 进行函数调用才能获得基本类型的 ivars。
typedef int (*XYIntGetVariableFunction)(id object, const char* variableName);
XYIntGetVariableFunction intVariableFunction = (XYIntGetVariableFunction)object_getIvar;
int result = intVariableFunction(object, intVarName);
我制作了一个有用的小宏来快速定义此类函数指针:
#define GET_IVAR_OF_TYPE_DEFININTION(type, capitalized_type) \
typedef type (*XY ## capitalized_type ## GetVariableFunctionType)(id object, Ivar ivar); \
XY ## capitalized_type ## GetVariableFunctionType XY ## capitalized_type ## GetVariableFunction = (XY ## capitalized_type ## GetVariableFunctionType)object_getIvar;
然后,对于基本类型,您需要指定对宏的调用(参数,例如 (long long, LongLong) 将适合):
GET_IVAR_OF_TYPE_DEFININTION(int, Int)
之后,用于接收 int(或指定)变量类型的函数变得可用:
int result = XYIntGetVariableFunction(object, variableName)
返回的值是对象中正确位置的值;只是不是正确的类型。对于int
and BOOL
(但不是float
),您可以将指针转换为int
or BOOL
,因为指针和 int 的大小相同,并且它们可以相互转换:
(int)object_getIvar(obj, myIntVar)
它可能将值装箱在 NSNumber 中。您可以通过 NSLogging 返回的 id 的类名来验证这一点,如下所示:
id returnedValue = object_getIvar(self, myIntVar);
NSLog(@"Class: %@", [returnedValue className]);
编辑:我在这里发现了另一个类似的问题:Handling the return value of object_getIvar(id object, Ivar ivar)
从我自己的实验来看,我最初的假设似乎是不正确的。int 和 float 以及其他原语似乎作为实际值返回。但是,使用 ivar_getTypeEncoding 来验证返回的值是否是您期望的类型是合适的。
可以object_getInstanceVariable
直接使用:(没测试过)
void *ptr_to_result;
object_getInstanceVariable(obj, "intvarname", &ptr_to_result);
float result = *(float *)ptr_to_result;