Во-первых, NSNumber * цифра - это «Указатель на тип NSNumber», а тип NSNumber - это объект Objective-C. В общем, если иное не указано где-то в документации, эмпирическое правило в объектно-ориентированном программировании таково: «Внутренние детали того, как объект выбирает представление своего внутреннего состояния, являются частными для реализации объектов и должны рассматриваться как черные ящик «. Опять же, если в документации не указано, что вы можете поступить иначе, вы не можете предполагать, что NSNumber использует примитивный тип C int
для хранения значения 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
, это первые четыре байта того, на что указывает numero
(что для объекта в Obj-C всегда isa
, класс объектов). Я подозреваю, что вы «хотели» сделать, это скопировать указатель на экземпляр объекта (значение Numberro), и в этом случае вы должны были использовать &numero
. Это проблема, если вы используете GC, поскольку буфер, используемый NSMutableData
, не сканируется (т. Е. Система GC больше не будет «видеть» объект и возвращать его, что в значительной степени является гарантией случайного сбоя при немного позже.)
Надеемся, очевидно, что даже если вы поместите указатель на экземплярный объект NSNumber
в data
, этот указатель имеет значение только в контексте процесса, который его создал. Указатель на этот объект становится еще менее значимым, если вы отправляете этот указатель на другой компьютер - у принимающего компьютера нет (практичного, тривиального) способа чтения памяти, на которую указывает указатель, в отправляющем компьютере.
Поскольку у вас, похоже, возникают проблемы с этой частью процесса, позвольте мне дать рекомендацию, которая сэкономит вам бесчисленные часы отладки некоторых чрезвычайно сложных ошибок реализации, с которыми вы обязательно столкнетесь:
Оставьте всю эту идею, пытаясь отправить необработанные двоичные данные между машинами и просто отправить между ними простую информацию в формате ASCII / UTF-8.
Если вы думаете, что это будет как-то медленно или неэффективно, то позвольте мне порекомендовать вам сначала рассказать об этом, используя упрощенную строковую версию ASCII / UTF-8. Поверьте мне, отладка необработанных двоичных данных не доставляет удовольствия, а способность просто NSLog(@"I got: %@", dataString)
на вес золота, когда вы отлаживаете свои неизбежные проблемы. Затем, как только все замерзло, и вы уверены, что вам больше не нужно вносить изменения в то, что вам нужно обменять, «порт» (из-за отсутствия лучшего слова) этой реализации в бинарную версию. если и только если , профилирование с помощью Shark.app идентифицирует его как проблемную область. Для справки, в эти дни я могу scp
файл между машинами и насыщать гигабитную ссылку с передачей. scp
, вероятно, для сжатия и шифрования данных приходится выполнять примерно в пять тысяч раз больше обработки на байт, чем это простое форматирование со скоростью 80 МБ / с. Тем не менее, на современном оборудовании этого едва хватает, чтобы сдвинуть с места индикатор работы процессора в строке меню.