頭と尻尾はくれてやる!

iOSアプリなどの開発日記です


NSCodingでNSData化するとサイズがかなり大きくなる?

GKSessionクラスを使ってNSData型のデータをヘッダー付きで送信することはできた、ってのが前のエントリー(GKSessionでヘッダーとNSDataを送信する方法)なんだけどさ、これをいじってる時にふとデータのサイズが妙に大きくなってるんじゃない?って気がしたんだ。

ちょっとくらい大きくなるくらいだったらいいんだけど、GKSession使って送信するんだからやっぱりなるべく小さい方がよさそうじゃない?
AppleのドキュメントにだってGKSessionでデータ送信するデータのサイズはなるべく1000バイト以下にせえよって記述もあるしね。
最高のパフォーマンスを引き出 すには、データオブジェクトのサイズを小さく(長さ1000バイト以下に)することをお勧めしま す。1000バイトより大きいメッセージは、小さい固まりに分割して送信先で組み立てなおさなけれ ばならないことがあります。それにより遅延やオーバヘッドが増える可能性があります。
*Game Kit プログラミングガイドより


そこでどのくらいのサイズになりそうなのか簡単なテストをしてみたんだよね。
次のソースはstring1とstring2って文字列をNSDataに変換してそのサイズを見るって内容なんだ。二つの文字列はともに5文字ずつだよ。
-(void) testTransfer
{
    NSString *string1 = @"Hello";
    NSString *string2 = @"World";
    
    //case1
    NSString *allString = [NSString stringWithFormat:@"%@,%@",string1,string2];
    NSData *data = [allString dataUsingEncoding: NSUTF8StringEncoding];
    NSLog(@"[data length] = %d[bytes]",[data length]);//11[bytes]
    
    
    //case2
    Transfer *transfer = [[Transfer alloc] init];
    transfer.array = [NSArray arrayWithObjects:string1,string2, nil];
    NSData *transferData = [NSKeyedArchiver archivedDataWithRootObject:transfer];
    NSLog(@"[transferData length] = %d[bytes]",[transferData length]);//313[bytes]

        
    //case3
    Transfer2 *transfer2 = [[Transfer2 alloc] init];
    transfer2.string1 = string1;
    transfer2.string2 = string2;
    NSData *transfer2Data = [NSKeyedArchiver archivedDataWithRootObject:transfer2];
    NSLog(@"[transfer2Data length] = %d[bytes]",[transfer2Data length]);//260[bytes]
    
}
case1はNSStringのdataUsingEncoding:メソッドを使ってNSData型に変換してるよね。
この時二つの文字列を区切るのにコンマを使っているからトータルで5+5+1で11バイトになったんだな。まあこれは納得だよね。

case2はお待ちかねのNSCoding使ってNSData型にする場合で、二つの文字列を配列(NSArray)に放り込んで、それをNSData型にしてるよ。
エンコードのためにTransferってクラスを作ったんだけど、もちろんこのクラスはヘッダーにNSCodingプロトコル使うぜって宣言してるからね。
Transferクラスでは次のようにしてエンコードしてるんだよね。
//in 'Transfer' class
- (void)encodeWithCoder:(NSCoder *)encoder
{
    [encoder encodeObject:_array forKey:@"array"];
}
ここで_arrayはTransferクラスのプロパティだよ。
そうそう、NSCodingプロトコル使うって宣言するとデコードの部分も必須だけどここでは省略してるよ。
結果はというと、313バイトになったんだ。
これちょっとすごくなくなくなーい?ってくらいの驚きだね、だって元は10バイトのデータなんだよ?
あ、これってもしかしてNSArray使ったからかな?と思って今度はもう少し直球勝負してみたんだ。
それがcase3なんだけど、次のように配列に入れるんじゃなくて文字列としてエンコードしてみたんだよね。
//in 'Transfer2' class
- (void)encodeWithCoder:(NSCoder *)encoder
{
    [encoder encodeObject:_string1 forKey:@"string1"];
    [encoder encodeObject:_string2 forKey:@"string2"];
}
このcase3の結果は260バイト。
ちょっとだけ減ったけど元が10バイトのデータかと思うとやっぱりでかいよね。
実際に使う場面を考えたら簡単に1000バイトを超えそうだもんな。

これは困ったな、、、しょうがない、隠し味にオリーブオイルを使うしかないね!
スポンサーサイト




<< さすが傑作!「坂の上の雲」  TopPage  GKSessionでヘッダーとNSDataを送信する方法 >>

コメント


管理者にだけ表示を許可する
 

トラックバック

トラックバックURL
https://ringsbell.blog.fc2.com/tb.php/544-f075b3fd




Copyright ©頭と尻尾はくれてやる!. Powered by FC2 Blog. Template by eriraha.