1

両側で KVC を使用して値にアクセスし、GameCenter を介してオブジェクトを同期しようとしています。を使用して数値を設定setValue:forKey:するには、それらがNSNumberオブジェクトである必要があります。intfloatなどのエンコーディングを渡すオブジェクトも
NSValue initWithBytes:objCType:提供します。NSValue

エンコーディングを手動でチェックする代わりに、より良い解決策がありますか?

- (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];
}

これが進むべき道である場合、KVC で処理する必要がNSNumberある唯一のサブクラスはありますか?NSValue

4

1 に答える 1

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];
}
于 2012-07-19T02:08:02.893 に答える