object_getInstanceVariable适用于float,int,bool,但不适用于double吗? [英] object_getInstanceVariable works for float, int, bool, but not for double?

查看:79
本文介绍了object_getInstanceVariable适用于float,int,bool,但不适用于double吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有object_getInstanceVariable作为

I've got object_getInstanceVariable to work as here however it seems to only work for floats, bools and ints not doubles. I do suspect I'm doing something wrong but I've been going in circles with this.

float myFloatValue;
float someFloat = 2.123f;
object_getInstanceVariable(self, "someFloat", (void*)&myFloatValue);

有效,并且myFloatValue = 2.123

works, and myFloatValue = 2.123

但是当我尝试

double myDoubleValue;
double someDouble = 2.123f;
object_getInstanceVariable(self, "someDouble", (void*)&myDoubleValue);

我得到myDoubleValue = 0.如果我尝试在功能之前设置myDoubleValue. double myDoubleValue = 1.2f,当我在object_getInstanceVariable调用后读取它时,该值保持不变.在上面的getinstancevar函数之前,将myIntValue设置为其他值,则应返回2,即.它已更改.

I get myDoubleValue = 0. If I try to set myDoubleValue before the function eg. double myDoubleValue = 1.2f, the value is unchanged when I read it after the object_getInstanceVariable call. Setting myIntValue to some other value before the getinstancevar function above returns 2 as it should, ie. it has been changed.

然后我尝试

Ivar tmpIvar = object_getInstanceVariable(self, "someDouble", (void*)&myDoubleValue);

如果我执行ivar_getName(tmpIvar),我会得到"someDouble",但myDoubuleValue = 0仍然!然后我尝试ivar_getTypeEncoding(tmpIvar)并得到应有的"d".

If I do ivar_getName(tmpIvar) I get "someDouble", but myDoubuleValue = 0 still! Then I try ivar_getTypeEncoding(tmpIvar) and I get "d" as it should be.

因此,总结一下,如果typeEncoding = float可以工作,如果它是双精度型,则不会设置结果,但可以正确读取变量,并且返回值(Ivar)也正确.

So to summarize, if typeEncoding = float, it works, if it is a double, the result is not set but it correctly reads the variable and the return value (Ivar) is also correct.

我一定在犯一些我看不见的基本错误,因此,如果有人指出来,我将不胜感激.

I must be doing something basic wrong that I cant see so I'd appreciate if someone could point it out.

推荐答案

object_getInstanceVariable是一个混乱的小功能.它是

object_getInstanceVariable is a confused little function. It is documented that the last parameter is a void ** parameter—that is, you pass the address of a void * variable and get a pointer to the instance variable—but it is implemented as if it was a void * parameter—that is, you pass the address of the variable that you want to hold a copy of the instance variable. The problem is that the implementation ignores the size of the instance variable and just does a pointer copy. So anything that's the same size as a pointer will work perfectly. If you're running on a 32-bit architecture, only the high 32 bits will be copied. (You should witness the same behavior with a long long instance variable as well.)

解决方案是使用主要API,

The solution is to use the primary API, key-value coding, using -valueForKey:.

另一种解决方案:如果您想编写一个固定版本,例如说是NSObject的类别,它将看起来像这样:

The other solution: If you wanted to write a fixed version, say as a category for NSObject, it would look something like this:

@implementation NSObject (InstanceVariableForKey)

- (void *)instanceVariableForKey:(NSString *)aKey {
    if (aKey) {
        Ivar ivar = object_getInstanceVariable(self, [aKey UTF8String], NULL);
        if (ivar) {
            return (void *)((char *)self + ivar_getOffset(ivar));
        }
    }
    return NULL;
}

@end

然后您的代码将如下所示:

Then your code would look like this:

double myDoubleValue = *(double *)[self instanceVariableForKey:@"someDouble"];

这篇关于object_getInstanceVariable适用于float,int,bool,但不适用于double吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆