1

我有一系列最终可以表示为的数据BOOLs。我想将它们转换BOOLsbytes这样我可以把它们放在一个NSData对象中并通过网络发送它们。我知道我可以将 8BOOLs放入 1byte中。我将如何打包这些数据?另外,一旦收到,我将如何将其解压缩回BOOLs?网络部分是通过 处理的GameCenter,所以我只需要担心打包和解包数据。

4

3 回答 3

3

第一:你真的想要或需要将 8 个布尔值打包成一个字节吗?打包节省了带宽,但增加了很多复杂性和麻烦;多年来,它一直是错误的强大来源。

如果您确实想这样做,请使用掩码和逻辑运算符。

 #define kMill 1
 #define kDrill 2
 #define kFill  4
 #define kALL   kMill|kDrill|kFill;

 unsigned char TheData;

- (BOOL) isMilled { return (theData&kMill)!=0; }
- (void) setMilled: (BOOL) flag { 
      if (flag) {theData |= kMill;} 
      else {theData = theData & (kAll^kMill;}}

C 联合对此有一些支持,但最好避免使用该功能。

作为一项规则,避免过早优化。简单地表示您的数据,然后在出现性能问题时通过网络查看压缩表示。

于 2013-02-24T17:22:12.133 回答
3

您可以将您的数据视为的集合,并使用

  • CFBitVector及其可变对应物CFMutableBitVector

这是一种 CoreFoundation 类型,用于管理位值的集合,或者在较低级别上,

这两种方法都提供函数/宏来设置大位向量中的各个位,并且您可以访问底层缓冲区以将位向量包装到NSData对象中并返回。

示例CFBitVector

// Create a bit vector and set some bits:
CFIndex numBits = 256;
CFMutableBitVectorRef bitvec = CFBitVectorCreateMutable(NULL, 0);
CFBitVectorSetCount(bitvec, numBits);
CFBitVectorSetBitAtIndex(bitvec, 0, 1);
CFBitVectorSetBitAtIndex(bitvec, 5, 1);
CFBitVectorSetBitAtIndex(bitvec, 255, 1);

// Pack into NSData:
size_t nbytes = (CFBitVectorGetCount(bitvec) + 7)/8;
NSMutableData *data = [NSMutableData dataWithLength:nbytes];
CFBitVectorGetBits(bitvec, CFRangeMake(0, CFBitVectorGetCount(bitvec)), [data mutableBytes]); 

// And back to CFBitVector:
CFBitVectorRef bitvec2 = CFBitVectorCreate(NULL, [data bytes], [data length] * 8);
// Test a value:
BOOL bit5set = CFBitVectorGetBitAtIndex(bitvec2, 5) != 0;

位串示例:

// Create bit-string and set some bits:
int numBits = 1024;
bitstr_t *mybits = bit_alloc(numBits);
bit_nclear(mybits, 0, numBits - 1);
bit_set(mybits, 5);
bit_set(mybits, 17);

// Pack into NSData:
NSData *data = [NSData dataWithBytes:mybits length:bitstr_size(numBits)*sizeof(bitstr_t)];

// And back to bit-string:
int bitcount = (int)[data length] * 8;
const bitstr_t *mybits2 = [data bytes];
// Test a value:
BOOL bit5set = bit_test(mybits2, 5) != 0;
于 2013-02-24T22:30:21.773 回答
1

不,您不能将 8 个 BOOLS 作为 BOOL 放入 1 个字节!= 布尔值(1/0 = 1 位) BOOL 是短的,仅在 99% 的情况下 1/0

也就是说,如果你假设它只是 1/0 位移位的东西成一个字节!

    UInt8 b = 0;


    BOOL bool1 = YES, bool2 = NO, bool3 = YES;
    if(bool1) b = b | 1;
    if(bool2) b = b | 2;
    if(bool3) b = b | 4;

    // insert code here...
    NSLog(@"%@", [NSData dataWithBytes:&b length:1]);

    bool1 = b & 1;
    bool2 = b & 2;
    bool3 = b & 4;

    NSLog(@"%d%d%d", bool1, bool2, bool3);

但这不值得:D

于 2013-02-24T17:28:26.713 回答