How do I get the int value from object_getIvar(self, myIntVar) as it returns a pointer

不问归期 提交于 2019-12-18 11:44:17

问题


if the variable in object_getIvar is a basic data type (eg. float, int, bool) how do I get the value as the function returns a pointer (id) according to the documentation. I've tried casting to an int, int* but when I try to get that to NSLog, I get error about an incompatible pointer type.


回答1:


Getting:

myFloat = 2.34f;

float myFloatValue;
object_getInstanceVariable(self, "myFloat", (void*)&myFloatValue);

NSLog(@"%f", myFloatValue);

Outputs:

2.340000

Setting:

float newValue = 2.34f;
unsigned int addr = (unsigned int)&newValue;

object_setInstanceVariable(self, "myFloat", *(float**)addr);

NSLog(@"%f", myFloat);

Outputs:

2.340000




回答2:


For ARC:

Inspired by this answer: object_getIvar fails to read the value of BOOL iVar. You have to cast function call for object_getIvar to get basic-type ivars.

typedef int (*XYIntGetVariableFunction)(id object, const char* variableName);
XYIntGetVariableFunction intVariableFunction = (XYIntGetVariableFunction)object_getIvar;
int result = intVariableFunction(object, intVarName);

I have made a small useful macro for fast definition of such function pointers:

#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;

Then, for basic types you need to specify calls to macro (params e.g. (long long, LongLong) will fit):

GET_IVAR_OF_TYPE_DEFININTION(int, Int)

And after that a function for receiving int(or specified) variable type become available:

int result = XYIntGetVariableFunction(object, variableName)



回答3:


The value that is returned is the value from the right place in the object; just not the right type. For int and BOOL (but not float), you could just cast the pointer to an int or BOOL, since pointers and ints are the same size and they can be cast to each other:

(int)object_getIvar(obj, myIntVar)



回答4:


It's probably boxing the value in an NSNumber. You can verify this by NSLogging the returned id's className, like so:

id returnedValue = object_getIvar(self, myIntVar);
NSLog(@"Class: %@", [returnedValue className]);

Edit: I found another question just like this one here: Handling the return value of object_getIvar(id object, Ivar ivar)

From my own experimentation, it would appear that my original assumption was incorrect. int and float and other primitives appear to be returned as the actual value. However, it would be appropriate to use ivar_getTypeEncoding to verify that the returned value is the type that you're expecting it to be.




回答5:


you can use object_getInstanceVariable directly: (haven't tested it)

void *ptr_to_result;
object_getInstanceVariable(obj, "intvarname", &ptr_to_result);
float result = *(float *)ptr_to_result;


来源:https://stackoverflow.com/questions/1217139/how-do-i-get-the-int-value-from-object-getivarself-myintvar-as-it-returns-a-p

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!