【问题标题】:NSValue/NSNumber creation of a given encoding/objCTypeNSValue/NSNumber 创建给定的 encoding/objCType
【发布时间】:2012-07-16 02:40:36
【问题描述】:

我正在尝试通过 GameCenter 同步对象,并在两侧使用 KVC 访问它们的值。使用setValue:forKey: 设置数值要求它们是NSNumber 对象。
NSValue initWithBytes:objCType: 给了我NSValue 对象,甚至可以传递 intfloat 和这样的。

你们有更好的解决方案而不是手动检查编码吗?

- (NSValue*)smartValueWithBytes:(void*)value objCType:(const char*)type
{
    if (0 == strcmp(type, @encode(int)))
    {
        int tmp;
        memcpy(&tmp, value, sizeof(tmp));
        return [NSNumber numberWithInt:tmp];
    }
    if (0 == strcmp(type, @encode(BOOL)))
    {
        BOOL tmp;
        memcpy(&tmp, value, sizeof(tmp));
        return [NSNumber numberWithBool:tmp];
    }
    //etc...
    return [NSValue valueWithBytes:value objCType:type];
}

如果这是要走的路,NSNumber 是我需要为 KVC 处理的唯一 NSValue 子类吗?

【问题讨论】:

  • 顺便说一句——这有一个错误。应该是if ( 0 == strcmp( type, @encode( int ) ) )
  • 如果你说[NSNumber valueWithBytes:objCType:]会发生什么?由于NSNumberNSValue 的子类,它应该(理论上)响应NSValue 所做的所有方法。不过我可以想象它很古怪。
  • 另外,您可以这样做(例如):[ NSNumber numberWithInt:(int){ *(int*)value } ] 这可以节省您的打字时间...
  • 啊.. 我只是继续...上面的代码)用于数字类型。虽然不确定这是一个好习惯:)
  • @nielsbot 更不用说 memcpy 有一个 biiiigg 开销......

标签: objective-c ios encoding nsnumber nsvalue


【解决方案1】:

这是我对问题的解决方案,只对浮点值进行了专门化(因为它们很奇怪!)

NSValue *safeValueForKVC(const void *input, const char *type)
{
    const char numericEncodings[] = { 
        'c',
        'i', 
        's', 
        'l', 
        'q', 
        'C', 
        'I',
        'S',
        'L',
        'Q',
        'f',
        'd',
    };
    const size_t sizeEncodings[] = {
        sizeof(char),
        sizeof(int),
        sizeof(short),
        sizeof(long),
        sizeof(long long),
        sizeof(unsigned char),
        sizeof(unsigned int),
        sizeof(unsigned short),
        sizeof(unsigned long),
        sizeof(unsigned long long),
        sizeof(float),
        sizeof(double),
    };

    int typeLen = strlen(type);

    if (typeLen == 1)
    {
        for (int i = 0; i < sizeof(numericEncodings); i++)
        {
            if (type[0] == numericEncodings[i])
            {
                // we have a numeric type, now do something with it
                if (i == 10)
                {
                    // floating-point value
                    float fValue = 0;

                    memcpy(&fValue, input, sizeEncodings[i]);

                    return [NSNumber numberWithFloat:fValue];
                }
                if (i == 11)
                {
                    // double value
                    double dValue = 0;

                    memcpy(&dValue, input, sizeEncodings[i]);

                    return [NSNumber numberWithDouble:dValue];
                }

                // standard numeric value, simply padding with false bits should work for any reasonable integer represetntation
                long long value = 0;
                memcpy(&value, input, sizeEncodings[i]);

                return [NSNumber numberWithLongLong:value];
            }
        }
    }

    return [[NSValue alloc] initWithBytes:input objCType:type];
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多