我正在尝试通过GameCenter同步对象,并在两侧使用KVC访问它们的值。使用setValue:forKey:
设置数值需要它们为NSNumber
个对象
NSValue initWithBytes:objCType:
为NSValue
个对象提供了 int , float 等编码。
你们有没有更好的解决方案,而不是手动检查编码?
- (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
子类是什么?
答案 0 :(得分: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];
}