最終的に として表すことができる一連のデータがありますBOOLs
。これらを変換BOOLs
して、オブジェクトbytes
に入れてネットワーク経由で送信できるようにします。8を 1NSData
に収めることができることを知っています。このデータをどのようにパックしますか? また、受け取ったら、どのように解凍して に戻しますか? ネットワーキングの部分は を通じて処理されるため、データのパックとアンパックについてのみ心配する必要があります。BOOLs
byte
BOOLs
GameCenter
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;
最初に: 本当に 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 共用体はこれをある程度サポートしていますが、その機能は避けるのが最善です。
原則として、時期尚早の最適化は避けてください。データを単純に表現し、パフォーマンスの問題が発生した場合はネットワーク経由で圧縮された表現を調べます。
いいえ、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