0

我正在实现一个多人游戏,我必须使用以下方式在玩家之间发送数据:

 [self sendData:data mode:GKMatchSendDataReliable];

而不是像本教程中那样使用多个 c-structs ( http://www.raywenderlich.com/3325/how-to-make-a-simple-multiplayer-game-with-game-center-tutorial-part-22 ) ,我创建了一个 Message 对象和一个名为 Submessage 的 Message 子类。创建了子类,因此我避免在每条消息中发送不必要的变量,以最小化发送的每个数据包的大小。然后我使用 NSCoding 对消息进行编码和解码。

这些类如下所示:

消息.h

 @interface Message : NSObject <NSCoding>

 @property int messageType;

 - (void)encodeWithCoder:(NSCoder*)coder;

 - (id)initWithCoder:(NSCoder*)coder;

消息编码器方法

-(void) encodeWithCoder:(NSCoder *)coder{
     [coder encodeInt:messageType forKey:@"messageType"];
}
-(id)initWithCoder:(NSCoder *)coder {
    self = [super init];
    messageType = [coder decodeIntForKey:@"messageType"];
    return self;
}

子消息.h

 @interface Submessage : Message <NSCoding>

 @property float additionalParameter1;

 - (void)encodeWithCoder:(NSCoder*)coder;

 - (id)initWithCoder:(NSCoder*)coder;

子消息编码器方法

- (void)encodeWithCoder:(NSCoder *)coder{
    [super encodeWithCoder:coder];
    [coder encodeFloat:additionalParameter1 forKey:@"float"];
}

- (id)initWithCoder:(NSCoder *)coder {
    self = [super init];
    [self initWithCoder:coder];
    floatParameter1 = [coder decodeFloatForKey:@"floatParameter1"];
    return self;
}

收到数据后,我使用以下方法将其取消归档:

 Message *thisMessage = [NSKeyedUnarchiver unarchiveObjectWithData:data];

但是,当我发送子消息时,这不起作用。如何确定数据是消息类型还是子消息类型?我应该如何实现它才能像在 c-struct 案例中一样工作?

4

2 回答 2

0

如果我理解您的问题,您想在运行时确定哪种对象未归档。您可以像使用任何对象一样测试它的类,然后适当地使用它。像这样:

id obj = [NSKeyedUnarchiver unarchiveObjectWithData:data];
if ([obj isKindOfClass:[Submessage class]]) {
    Submessage * submessage = (Submessage *)obj;
    // do something with submessage
} else if ([obj isKindOfClass:[Message class]]) {
    Message * message = (Message *)obj;
    // do something with message
}

-isKindOfClass:将检测子类,这就是为什么第一个条件需要在这里检查子类。)

于 2013-03-19T16:09:49.090 回答
0

您的子类 initWithCoder 似乎不正确。根据文档:

如果超类采用 NSCoding 协议,则首先将 initWithCoder: 的返回值分配给 self:

- (id)initWithCoder:(NSCoder *)coder {
    self = [super initWithCoder:coder];
    if (self) {
        // Implementation continues.
    }
    return self;
}

但既然你说消息长度应该最小化,我建议使用 MessagePack ( http://msgpack.org/ ) 转换为紧凑的二进制表示。你必须自己处理更多,但它应该更有效率:)

于 2013-03-20T17:58:11.917 回答