потеря данных при отправке через тип NSData

В настоящее время я нахожусь в середине реализации сетевого уровня своей игры, я делаю успехи, однако я наткнулся на что-то очень странное, и я надеялся, что кто-то может пролить немного мощи:

Перед отправкой данных я кодирую их в тип NSData (message.cards = [MovePlayer beginEncodeMyCards:myCards];), а затем назначаю их указателю (message.cards)

MessageMove message;
message.message.messageType = kMessageTypeMove;
/**/message.cards = [MovePlayer beginEncodeMyCards:myCards];/**/
NSData *data = [NSData dataWithBytes:&message length:sizeof(message)];

Если я сделаю все декодирование на стороне клиента следующим образом:

MessageMove *myMessage  = (MessageMove *) [data bytes];
/**/myCards = [MovePlayer beginDecodeMyCards:myMessage->cards cardArray:myCards];/**/

все работает нормально, я могу декодировать myMessage->cards, однако, когда я пытаюсь сделать то же самое после удаленной отправки объекта, я вижу правильный тип сообщения (kMessageTypeMove), но не данные карточек (myMessage->cards).

если кто-то может пролить свет на это, я был бы очень признателен

огромное спасибо


person godzilla    schedule 03.05.2012    source источник


Ответы (1)


tl;dr, используйте NSCoding для сериализации ваших объектов.

Вы не можете отправлять указатели другому процессу, потому что все указатели на другой стороне будут неправильными.

Допустим, на отправляющей машине у вас есть это:

NSLog(@"cards: %p", message.cards);
//prints "cards: 0xDEADBEEF"

Это говорит о том, что кусок памяти для объекта NSArray* начинается с адреса памяти 0xDEADBEEF. Это все правильно на данный момент.

Теперь вы отправляете этот указатель 0xDEADBEEF на другой компьютер. Компьютер получает указатель, но в памяти 0xDEADBEEF нет NSArray на другом компьютере. В этой области памяти может быть что угодно. Вы отправили указатель, но на самом деле не отправили с ним никаких данных.

Короче говоря, просто используйте NSCoder для сериализации, потому что это очень хорошо.

person Tom Dalling    schedule 03.05.2012
comment
спасибо за ответ, у вас есть пример, которому я могу следовать? - person godzilla; 03.05.2012
comment
Оказывается, я выполняю сериализацию, о которой вы говорили, в beginEncode, этот метод возвращает указатель на NSData, содержащий информацию о моих картах. Я до сих пор не уверен, как я могу отправить все значение, а не только указатель.... - person godzilla; 03.05.2012
comment
В принципе, не делайте этого: [NSData dataWithBytes:&message length:sizeof(message)]. Сделайте это: [NSKeyedArchiver archivedDataWithRootObject:message]. - person Tom Dalling; 04.05.2012