2012-05-29 2 views
0

클래스에 ccColor3B 속성이있어 NSCoding을 사용하여 유지하려고합니다. 이것을 어떻게 할 수 있습니까? NSCoder는 그것을 허용하는 방법이없는 것 같습니다. 그래서 같은 바이트로ccColor3B 필드의 NSCoding

답변

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

인코딩 :

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 (컬러)를 사용해야합니다. –

+0

@JoeWreschnig이 구현에서 ** 제로 ** 위험성을 느낍니다 ... 나에게 설명하고 * 설명하는 * 매우 위험한 스타일. 고정 된 번호를 사용하는 데는 좋은 이유가 있습니다. 3 요소 바이트 시퀀스는 구현시 인코딩 된 것이고 '색상'은 인코딩되지 않습니다. 물론, 나는 확장 된 오류 처리 및 버전 관리를 OP에 남겼습니다. pedantry : * 구현은 여러 활성 멤버를 사용하면서 구현에서 유니온의 메모리 레이아웃을 가정합니다. 그것은 불특정 행동입니다. 표준에서는 멤버의 메모리가 정렬되거나 중첩된다는 보장을하지 않습니다. – justin

+0

위험은 sizeof (var) (또는 sizeof (type)이 아닌 경우)를 사용하는 대신 구조체 크기를 하드 코딩하는 것입니다. 앞에서 말했듯이이 구현에는 아무런 문제가 없지만 관용구가 잘못 되었기 때문에이 구현에서는 아무런 위험도 없습니다. '3'대신 '2'를 쓰는 사람이 있으면 경고없이 분리됩니다. C는 형식이 잘린 유니온 (및 iirc 심지어 포인터 캐스트,하지만 컴파일러 경고를 자주 방해하는) 등가 서명되지 않은/서명 된 형식의 사용하는 방식으로 작동합니다. –

0

임시 형식이 안전하지 않은 변환을 사용하는 것보다 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"]; 
관련 문제