我对Objective-C(和C本身)很新,需要从HTTP输出中使用NSData
。我从来没有真正使用字节数组或者不得不担心小/大端问题,并且已经努力编写以下方法来从NSNumber
读取具有指定长度的NSData
。
- (NSNumber *)readNumberWithLength:(NSUInteger)length
{
Byte k[length];
[data getBytes:k range:NSMakeRange(offset, length)]; // big endian byte array representing a number
offset += length;
NSNumber *number;
if (length==4) {
number = [NSNumber numberWithUnsignedInt:CFSwapInt32BigToHost(*(uint32_t *)k)];
} else if (length==2) {
number = [NSNumber numberWithUnsignedShort:CFSwapInt16BigToHost(*(uint16_t *)k)];
} else if (length==1) {
number = [NSNumber numberWithUnsignedChar:*(uint8_t *)k];
} else if (length==8) {
number = [NSNumber numberWithUnsignedLongLong:CFSwapInt64BigToHost(*(uint64_t *)k)];
} else {
number = [NSNumber numberWithInt:0];
}
return number;
}
我将NSData *data
和NSUInteger offset
声明为实例变量。
这段代码是否正确?有什么我应该担心的吗?我还没有在实际的设备上测试它(仅在模拟器上),它似乎对我来说很好。你有什么意见吗?
谢谢!
答案 0 :(得分:2)
代码看起来或多或少是正确的。
似乎很难。
我会感到惊讶 - 不是完全震惊,而是惊讶 - 从HTTP服务器返回的数据实际上只是原始字节。它是非常罕见的,并且在它的情况下,服务器的设计几乎肯定是错误的。 (肯定存在二进制HTTP响应是正确答案的情况,但这种情况非常罕见)。
除非你在谈论数据中数以千计的值,否则HTTP所暗示的开销几乎肯定会超过任何二进制的收益。解析字符串中已知的数值不是 繁琐,除非你真的经常这样做(这会使得首先使用HTTP不是特别有吸引力)。
服务器设计:足够公平。处理它的另一个有效理由是因为你无法改变这个难题的特定部分。
我个人会更自卫地实施代码:
验证本地数据大小是否与远程/网络大小相比具有预期的大小以防止意外(这可能是初始化或某些调试代码中的断言 - 我更喜欢在这样的情况下保持防御性)。
使用case语句而不是if / else if / else if / else序列。完全是一个美学决定,但它会有助于......
...通过记录处理length
是一个意外的值,即使只是在调试模式下也是如此。我认为一个意想不到的值大小可能对整体正确性非常不利?