まず、NSNumber *numero は「NSNumber 型へのポインター」であり、NSNumber 型は Objective-C オブジェクトです。一般に、ドキュメントのどこかに特に明記されていない限り、オブジェクト指向プログラミングの経験則は、「オブジェクトがその内部状態を表すために選択する方法の内部の詳細は、オブジェクトの実装にプライベートであり、黒として扱われるべきです.箱。" 繰り返しますが、別の方法で実行できるとドキュメントに記載されていない限り、NSNumber が指定した値int
を格納するためにC プリミティブ型を使用していると想定することはできません。int
以下は、「舞台裏」で何が起こっているかの大まかな概算ですappendBytes:numero
。
typedef struct {
Class isa;
double dbl;
long long ll;
} NSNumber;
NSNumber *numero = malloc(sizeof(NSNumber));
memset(numero, 0, sizeof(NSNumber));
numero->isa = objc_getClass("NSNumber");
void *bytes = malloc(1024);
memcpy(bytes, numero, sizeof(numero)); // sizeof(numero) == sizeof(void *)
これにより、NSMutableData
オブジェクトに追加しているのは、これまでに指してdata
いたものの最初の 4 バイトであることが少し明確になります (Obj-C のオブジェクトの場合、これは常にオブジェクト クラスです)。あなたが「やりたかった」ことは、ポインタをインスタンス化されたオブジェクト(numeroの値)にコピーすることだったと思います。によって使用されるバッファがスキャンされないため、GC を使用している場合、これは問題です(つまり、GC システムはオブジェクトを「認識」して再利用しなくなります。これは、後でランダムにクラッシュすることをほぼ確実に保証します)。 .)numero
isa
&numero
NSMutableData
NSNumber
インスタンス化されたオブジェクトへのポインターを to に置いたとしてもdata
、そのポインターは、それを作成したプロセスのコンテキストでのみ意味を持つことは明らかです。そのオブジェクトへのポインターは、そのポインターを別のコンピューターに送信すると、さらに意味がなくなります。受信側のコンピューターには、送信側のコンピューターでポインターが指すメモリを読み取る (実用的で簡単な) 方法がありません。
プロセスのこの部分で問題が発生しているように見えるので、遭遇するはずの非常に困難な実装バグをデバッグする時間を数え切れないほど節約できることをお勧めします。
マシン間で生のバイナリ データを送信しようとするこの考え全体を放棄し、マシン間で単純な ASCII/UTF-8 形式の情報を送信するだけです。
これでは速度が遅くなる、または非効率になると思われる場合は、最初に簡略化された ASCII/UTF-8 文字列化バージョンを使用してすべてを起動することをお勧めします。私を信じてください。生のバイナリ データをデバッグするのは楽しいことではありませんNSLog(@"I got: %@", dataString)
。避けられない問題をデバッグするときは、それだけの価値があります。次に、すべてがゲル化し、交換する必要があるものにこれ以上変更を加える必要がないと確信したら、その実装をバイナリのみのバージョンに「移植」します (適切な言葉がないため)。場合に限り、Shark.app を使用したプロファイリングで問題領域として識別されます。参考までに、最近ではscp
、マシン間でファイルを転送し、転送でギガビット リンクを飽和させることができます。 scp
データを圧縮して暗号化するには、80MB/秒を転送しながら、この単純な文字列化よりもおそらく 1 バイトあたり約 5,000 倍の処理を行う必要があります。しかし、最新のハードウェアでは、これはメニュー バーで実行されている CPU メーターを動かすのにかろうじて十分です。