1

最終的に として表すことができる一連のデータがありますBOOLs。これらを変換BOOLsして、オブジェクトbytesに入れてネットワーク経由で送信できるようにします。8を 1NSDataに収めることができることを知っています。このデータをどのようにパックしますか? また、受け取ったら、どのように解凍して に戻しますか? ネットワーキングの部分は を通じて処理されるため、データのパックとアンパックについてのみ心配する必要があります。BOOLsbyteBOOLsGameCenter

4

3 に答える 3

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 に答える
3

最初に: 本当に 8 つの bool を 1 バイトにパックしたい、またはパックする必要がありますか? パッキングは帯域幅を節約しますが、多くの複雑さと煩わしさを追加します。何年にもわたって、それはバグの強力な原因でした。

これを行いたい場合は、マスクと論理演算子を使用してください。

 #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 に答える
1

いいえ、8 つの BOOL を BOOL として 1 バイトに収めることはできません != ブール (1/0 = 1 ビット) BOOL は short であり、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 に答える