繁体   English   中英

iOS开发:如何将字符串封装在NSData对象中?

[英]iOS Development: How can I encapsulate a string in an NSData object?

我正在iPhone上构建多人游戏,我需要将字符串数据发送给游戏中的其他玩家。 为此,我需要以某种方式将NSString *字符串数据封装在NSData对象中。 这是我的代码结构的一个示例...

typedef struct 
{
   PACKETTYPE packetType;
   ??? stringToSend;  //<---not sure how to store this
} StringPacket;    

StringPacket msg;
msg.packetType = STRING_PACKET;
msg.stringToSend = ...  //  <---not sure what to do here
NSData *packet = [NSData dataWithBytes:&msg length:sizeof(StringPacket)];

所以我的问题是,如果StringPacket是在标头中定义的结构,则stringToSend属性应为哪种类型,以便我可以轻松调用NSDatadataWithBytes方法将数据包数据封装在NSData对象中?

感谢您的智慧!

首先,您应该通过[NSString UTF8String]将NSString转换为UTF8表示形式。 在那之后,我建议存储在数据包字符串长度中,然后-字符串字符本身。 所有这些都可以通过附加NSData来完成,该NSData是通过[NSData dataWithBytes:]从char *创建的

NSMutableData packet = [[NSMutableData alloc] init];
[packet appendBytes:&msg.packetType, sizeof(msg.packetType)];
char *str = [yourString UTF8String];
int len = strlen(str);
[packet appendBytes:(void*)&len, sizeof(len)];
[packet appendBytes:(void*)str, len];

要解析数据包,您应该执行以下操作:

NSData packet; // your packet
[packet getBytes:(void*)&packet.msg range:NSMakeRange(0, sizeof(packet.msg))];
int len;
[packet getBytes:(void*)&len range:NSMakeRange(sizeof(packet.msg), sizeof(len)];
NSData *strData = [packet subdataWithRange:NSMakeRange(sizeof(packet.msg) + sizeof(len)), packet.length];
NSString *str = [[NSString alloc] initWithData:strData encoding:UTF8Encoding];

自从我从内存中写入数据以来,可能会有一些错误,但是我想您会明白的。

如果您的字符串有最大长度,这很简单并且可以有效地完成。 因此,假设这些数据包的字符串最大长度为255,并且您已决定使用UTF-8对字符串进行编码(双方都需要同意他们使用的是哪种编码),则可以这样做:

typedef struct 
{
   PACKETTYPE packetType;
   uint8_t stringToSend[256];  // UTF8 string with max encoded length of 255 bytes
} StringPacket;    

StringPacket msg;
msg.packetType = STRING_PACKET;
[theString getCString:msg.stringToSend maxLength:256 encoding:NSUTF8StringEncoding];
NSData *packet = [NSData dataWithBytes:&msg length:sizeof(StringPacket)];

现在,您的数据包中将包含一个适当的C字符串,该字符串最多为255个字节的字符串数据和空终止符。 请注意,如果无法使用您给定的大小将字符串编码为UTF8,则该方法将返回NO,因此您的实际代码应实际对其进行检查和处理。

如果没有大小限制,则基本上可以执行相同的操作,但是必须处理动态分配内存,复制字节,创建数据并在适当的时间正确释放内存,因此它变得非常重要。涉及更多,但这是相同的基本思想。 另请参见-getBytes:maxLength:usedLength:encoding:options:range:remainingRange: ,在生成这些消息(字符串大小是动态的且完全未知)时,它非常有用。

但是,对于最简单的情况,上面的代码应该可以完成工作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM