2012-03-08 2 views
0

Я хочу отправить NSString сформировать еще один на другой iPhone/IPad через GameCenter , но столкновение с EXC_BAD_ACCESSОтправить NSString через Game Center

здесь в файле .h

typedef enum { 
    kMessageTypeRandomNumber = 0, 
    kMessageTypeGameBegin, 
    kMessageTypeSubmit, 
    kMessageTypeExchange, 
    kMessageTypePickup, 
    kMessageTypePass, 
    kMessageTypeGameOver 
} MessageType; 

typedef struct { 
    MessageType messageType; 
} Message; 

typedef struct { 
Message message; 
NSString *submitTile; 
} MessageSubmit; 

и здесь, в. м-файл

- (void)sendData:(NSData *)data { 
    NSError *error; 
    BOOL success = [[GCHelper sharedInstance].match sendDataToAllPlayers:data withDataMode:GKMatchSendDataReliable error:&error]; 
    if (!success) { 
     CCLOG(@"Error sending init packet"); 
     [self matchEnded]; 
    } 
} 
-(void)sendSubmit:(NSString *) submitTile { 
    MessageSubmit message; 
    message.message.messageType = kMessageTypeSubmit; 
    message.submitTile = submitTile; 
    NSData *data = [NSData dataWithBytes:&message length:sizeof(MessageSubmit)];  
    [self sendData:data]; 
} 

и функция и здесь, если я нажимаю на CCMenu изображения он будет вызывать onSubmit являются onSubmit функция

-(void)onSubmit 
{ 
    NSString *submitStr = @"1-7-7 =-7-8 1-7-9"; 

    [self sendSubmit:submitStr]; 
} 

и последний из которых является метод didReceiveData

- (void)match:(GKMatch *)match didReceiveData:(NSData *)data fromPlayer:(NSString *)playerID { 
    if (message->messageType == kMessageTypeSubmit) { 
     MessageSubmit * messageSubmit = (MessageSubmit *) [data bytes]; 
     NSString *submitStr = messageSubmit->submitTile; 

     NSLog(@"SubTile %@",submitStr); 
    } 
} 

он есть EXC_BAD_ACCESS на линии NSString *submitStr = messageSubmit->submitTile;.

Есть ли способ отправить сообщение NSString через iPhone/iPad?

ответ

1

Вы не можете сделать это:

NSData *data = [NSData dataWithBytes:&message length:sizeof(MessageSubmit)];  

... или это:

MessageSubmit * messageSubmit = (MessageSubmit *) [data bytes]; 

Вообще говоря, вы не можете просто отправить представление в памяти объектов вокруг как- является. Например, переменная экземпляра submitTile этого класса является указателем на объект NSString. Когда вы отправляете данные по сети, вы не отправляете эту строку, вы отправляете указатель - это всего лишь адрес памяти части памяти на отправляющем устройстве. Приемное устройство не будет иметь одну и ту же строку, хранящуюся в любом месте, и у него не будет одинакового адреса памяти, даже если бы он это сделал. Таким образом, у вас есть бессмысленный указатель, указывающий на никуда, и вы ожидаете, что он укажет на строку, которая не существует.

Самый простой способ сделать то, что вы хотите сделать, - сделать свой класс MessageSubmitNSCoding-совместимым. Сериализуйте его в NSData вместо того, чтобы просто сделать копию байтов.

+0

Можете ли вы показать пример использования NSCoding и NSData, которые вы указали. Thx –

+1

Прочтите документацию, попробуйте сделать это самостоятельно, и если вы терпите неудачу, отправьте еще один вопрос, объясняющий, что вы пробовали, и где он потерпел неудачу. – Jim

+1

«rtfm» - это плохой способ ответить кому-то (на stackoverflow всех мест). Downvoted. – Jonny

1

попробовать это:

Для кодирования:

NSData *data = [stringToEncode dataUsingEncoding:NSUTF8Encoding]; 

, которые вы можете отправить с помощью Game Center

Для декодирования:

NSString *recievedString = [NSString stringWithUTF8String:[recievedData bytes]]; 

Edit: Теперь я подумайте, что вы c даже поместите эти данные в одну из ваших структур сообщений и выполните то же самое с [NSData dataWithBytes:&message length:sizeof(MessageSubmit)] трюком и отправьте его.