2012-05-29 2 views
0

У меня есть свойство ccColor3B в моем классе, которое я хотел бы сохранить с помощью NSCoding. Как я могу это достичь? У NSCoder нет способа, который позволяет это.NSCoding a ccColor3B field

ответ

1

@Justin правильно, вы должны закодировать с помощью байт, но я думаю, что он над мыслительными вещами:

// encode 
ccColor3B input; 
[coder encodeBytes:&input length:sizeof(input) forKey:@"color"]; 

// decode 
ccColor3B output; 
const uint8_t *bytes = [coder decodeBytesForKey:@"color" returnedLength:NULL]; 
memcpy(&output, bytes, sizeof(output)); 
+0

@RichardJRossIII хорошо, я показывал иллюстративный пример, пытаясь избежать переносимости и тома «ABI gotchas», который должен сопровождать байт-копирующие структуры при сериализации :) – justin

0

Encode байт, например, так:

const NSUInteger BytesInCCColor = 3U; 
const uint8_t bytes[BytesInCCColor] = { color.r, color.g, color.b }; 
[coder encodeBytes:bytes length:BytesInCCColor forKey:@"color"]; 

Декодирование:

NSUInteger outLength = 0; 
const uint8_t* const bytes = 
    [coder decodeBytesForKey:@"color" returnedLength:&outLength]; 

if (NULL == bytes || BytesInCCColor != outLength) { 
    …uh-oh… 
} 
else { 
    color.r = bytes[0]; 
    color.g = bytes[1]; 
    color.b = bytes[2]; 
} 
+0

Я должен downvote это несмотря на то, что работает, потому что он делает это очень опасный стиль. Вы должны использовать sizeof (цвет), а не hardcoded 3. –

+0

@JoeWreschnig я вижу ** ноль ** опасность в этой реализации ... продолжайте и * объясните *, что «очень опасный стиль» для меня. есть веская причина для использования фиксированного числа: 3-компонентная последовательность байтов - это то, что закодировано в моей реализации, а не «цвет». конечно, я оставил расширенную обработку ошибок и управление версиями в OP. педантизм: * ваша * реализация предполагает макеты памяти союзов в реализации при использовании нескольких активных членов; это неуказанное поведение. стандарт не гарантирует, что память элементов будет выровнена или перекрыта. – justin

+0

Опасность - это практика размеров структуры жесткого кодирования, а не использование sizeof (var) (или когда это невозможно, sizeof (type)). Как я уже сказал, в этой реализации нет никакой опасности, потому что это само по себе правильно, но идиома плоха - все, что требуется, - это кому-то поставить «2» вместо «3», и она не разваливается без предупреждения. C действительно гарантирует тип-шлейфы (и iirc четные указатели, но которые часто мешают предупреждениям компилятора) эквивалентных неподписанных/подписанных типов работают так, как я их использую. –

0

Лучше, чем использование ad-hoc-небезопасных преобразований - это реализовать категорию на NSCoder, которая понимает, как с ней обращаться:

@implementation NSCoder (cocos2d) 

- (void)encodeUInt32:(uint32_t)i forKey:(NSString *)key { 
    union { int32_t s; uint32_t u; } v; 
    v.u = i; 
    [self encodeInt32:v.s forKey:key]; 
} 

- (uint32_t)decodeUInt32ForKey:(NSString *)key { 
    union { int32_t s; uint32_t u; } v; 
    v.s = [self decodeInt32ForKey:key]; 
    return v.u; 
} 

- (void)encodeColor3B:(ccColor3B)color forKey:(NSString *)key { 
    /* Storing 0xFF as the low 8 bits allows us to read/write ccColor3B 
     and ccColor4B interchangeably. */ 
    uint32_t rgba = (color.r << 24) | (color.g << 16) | (color.b << 8) | 0xFF; 
    [self encodeUInt32:rgba forKey:key]; 
} 

- (ccColor3B)decodeColor3BForKey:(NSString *)key { 
    ccColor3B c; 
    uint32_t rgba = [self decodeUInt32ForKey:key]; 
    c.r = rgba >> 24; 
    c.g = rgba >> 16; 
    c.b = rgba >> 8; 
    return c; 
} 

@end 

Тогда вы можете просто сделать:

self.color = [decoder decodeColor3BForKey:@"color"]; 

и

[encoder encodeColor3B:self.color forKey:@"color"];