简体   繁体   English

从NSData读取NSNumber

[英]Read NSNumber from NSData

I pretty new to Objective-C (and C itself) and need to consume a NSData from a HTTP output. 我是Objective-C(和C本身)的新手,需要从HTTP输出中使用NSData I've never really worked with byte arrays or had to worry about little/big endian issues, and have struggled a bit to write the following method to read a NSNumber with a specified length from that NSData . 我从来没有真正使用字节数组或者不得不担心小/大端问题,并且已经努力编写以下方法来从该NSData读取具有指定长度的NSNumber

- (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;
}

I have NSData *data and NSUInteger offset declared as instance variables. 我将NSData *dataNSUInteger offset声明为实例变量。

Is this code correct? 这段代码是否正确? Is there anything I should worry about? 有什么我应该担心的吗? I haven't tested it on an actual device yet (only on the Simulator) and it seems to be working fine for me. 我还没有在实际的设备上测试它(仅在模拟器上),它似乎对我来说很好。 Do you have any comments on it? 你有什么评论吗?

Thank you! 谢谢!

The code looks more or less correct. 代码看起来或多或少是正确的。

Seems like the hard way. 似乎很难。

I would be surprised -- not totally shocked, but surprised -- that the data coming back from the HTTP server is really just raw bytes. 我会感到惊讶 - 不是完全震惊,而是惊讶 - 从HTTP服务器返回的数据实际上只是原始字节。 It would be exceptionally rare that it is and, in the case that it is, the design of the server is almost assuredly wrong. 它是非常罕见的,并且在它的情况下,服务器的设计几乎肯定是错误的。 (There are certainly cases where binary-HTTP-response is the right answer, but it is very very rare). (肯定存在二进制HTTP响应是正确答案的情况,但这种情况非常罕见)。

Unless you are talking about 100s of thousands of values in the data, the overhead implied by HTTP is almost certainly going to outweigh any gains of going binary. 除非你在谈论数据中的数千个值,否则HTTP所暗示的开销几乎肯定会超过二进制的任何收益。 Parsing known numeric values from a string isn't that onerous unless you are truly doing this constantly (which would make using HTTP not particularly attractive in the first place). 从字符串中解析已知的数值并不是那么繁重,除非你经常这样做(这会使得使用HTTP不是特别有吸引力)。


Server design: fair enough. 服务器设计:足够公平。 Another valid reason to deal with it is because you can't change that particular piece of the puzzle. 处理它的另一个有效理由是因为你不能改变这个特定的拼图。

I would personally implement the code more defensively: 我个人会更自卫地实现代码:

  • validate that the local data sizes are of the expected sizes compared to the remote / network sizes to prevent surprises (this could be assertions on initialization or in some debug code -- I prefer being über defensive in situations like these). 验证本地数据大小是否与远程/网络大小相比具有预期的大小以防止出现意外(这可能是初始化或某些调试代码中的断言 - 我更喜欢在这种情况下保持防御性)。

  • use a case statement instead of the if/else if/else if/else sequence. 使用case语句而不是if / else if / else if / else序列。 Completely an aesthetic decision, but it would contribute to... 完全是一个美学决定,但它会有助于......

  • ... deal with the length being an unexpected value by logging, even if only in debug mode. ...通过记录处理length是一个意外的值,即使只是在调试模式下。 I would think an unexpected value size would be potentially very bad for overall correctness? 我认为一个意想不到的值大小可能对整体正确性非常不利?

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

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