将NSData转换为int

时间:2011-09-07 10:53:12

标签: iphone objective-c ipad nsdata

我有一个NSData对象,长度是4个字节。这四个字节我是从另一个NSData对象中提取的,

fourByteData=[completeData subdataWithRange:NSMakeRange(0, 16)];

我的第一个问题是,上述陈述是否会为我提供完整数据的前四个字节。

如果是,那么如何将所有这些字节转换为等效的int。

7 个答案:

答案 0 :(得分:32)

268566528是您期望的值还是您期望的528?如果正确的值是528,那么字节顺序是big-endian但是cpu是little-endian,字节需要反转。

所以,如果正确的值应该是528那么:

NSData *data4 = [completeData subdataWithRange:NSMakeRange(0, 4)];
int value = CFSwapInt32BigToHost(*(int*)([data4 bytes]));

另请注意,网络标准订单是big-endian。

答案 1 :(得分:25)

该语句将为您提供前16个字节的数据,而不是4.要获得前4个字节,您需要将语句修改为:

fourByteData = [completeData subdataWithRange:NSMakeRange(0, 4)];

要将NSData对象中的数据读取为整数,您可以执行以下操作:

int theInteger;
[completeData getBytes:&theInteger length:sizeof(theInteger)];

如果只是将它转换为整数,则不需要获取前4个字节。您可以直接从上面的两行和completeData接收器

执行此操作

答案 2 :(得分:12)

不会得到16个字节的数据,因为范围是从偏移0到16个字节。

如果您有一个包含4个字节的NSData实例,那么您可以像这样进行简单的类型转换:

int value = *(int*)([data bytes]);

答案 3 :(得分:5)

- (unsigned)parseIntFromData:(NSData *)data{

    NSString *dataDescription = [data description];
    NSString *dataAsString = [dataDescription substringWithRange:NSMakeRange(1, [dataDescription length]-2)];

    unsigned intData = 0;
    NSScanner *scanner = [NSScanner scannerWithString:dataAsString];
    [scanner scanHexInt:&intData];

    return intData;
}

int numberOfChunks = [self parseIntFromData:data];

答案 4 :(得分:4)

iOS整数在第一个字节中存储LSB(最低有效字节),在最后一个字节中存储MSB。我有转换例程来测试所有这些东西。点击这里,

测试......

int i = 2342342;
    NSData * d1 = [Util dataFromInt:i]; // {[MSB], ..., ... ,[LSB]} <0023bdc6>
    NSData * d2 = [NSData dataWithBytes:&i length:4];  // {[LSB], ..., ... ,[MSB]} <c6bd2300>
    int ci1 = [Util intFromData:d1];
    int ci2 = [Util intFromDataReverse:d2];

Util.m

+ (NSData *) dataFromInt:(int)num {
    unsigned char * arr = (unsigned char *) malloc(sizeof(num) * sizeof(unsigned char));
    for (int i = sizeof(num) - 1 ; i >= 0; i --) {
        arr[i] = num & 0xFF;
        num = num >> 8;
    }
    NSData * data = [NSData dataWithBytes:arr length:sizeof(num)];
    free(arr);
    return data;
}

// {[MSB], ..., ... ,[LSB]}
+ (int) intFromData:(NSData *)data
{
    int intSize = sizeof(int); // change it to fixe length
    unsigned char * buffer = malloc(intSize * sizeof(unsigned char));
    [data getBytes:buffer length:intSize];
    int num = 0;
    for (int i = 0; i < intSize; i++) {
        num = (num << 8) + buffer[i];
    }
    free(buffer);
    return num;
}

// {[LSB], ..., ... ,[MSB]}
+ (int) intFromDataReverse:(NSData *)data
{
    int intSize = sizeof(int);// change it to fixe length
    unsigned char * buffer = malloc(intSize * sizeof(unsigned char));
    [data getBytes:buffer length:intSize];
    int num = 0;
    for (int i = intSize - 1; i >= 0; i--) {
        num = (num << 8) + buffer[i];
    }
    free(buffer);
    return num;
}

答案 5 :(得分:1)

它取决于您要转换的数据的Endianness表示法,与您的设备Endianness表示法有关。 wiki on Endianness

为了简单起见,你需要检查两种方法

NSData *data4 = [completeData subdataWithRange:NSMakeRange(0, 4)];
int value = CFSwapInt32BigToHost(*(int*)([data4 bytes]));

NSData *data4 = [completeData subdataWithRange:NSMakeRange(0, 4)];
int value = CFSwapInt32LittleToHost(*(int*)([data4 bytes]));

在解析数据时检查哪一个更有意义。

答案 6 :(得分:0)

假设此处的_vertexDataNSData 并且您知道缓冲区中需要哪些数据(类型),您可以使用NSData的.length属性遍历此块。 在此示例中,每个数据块都是 32字节(存储 8 x float 值),我感兴趣的是从第5个float值 < / p>

float a,b,c,d; //prepare some values, no need to initialize

// loop thru assuming 8 floats are stored after each other
for (NSUInteger v = 0; v < _vertexData.length; v += sizeof(float)*8 ) {

    // set a starting point for the range, here the 5th float
    NSUInteger shift = v + (sizeof(float)*4);

    // store result in a..
    [_vertexData getBytes:&a range:NSMakeRange(shift,sizeof(a))];

    // increase the starting point by the size of data before
    shift += sizeof(a);

    [_vertexData getBytes:&b range:NSMakeRange(shift,sizeof(b))];

    shift += sizeof(b);
    [_vertexData getBytes:&c range:NSMakeRange(shift,sizeof(c))];

    shift += sizeof(c);
    [_vertexData getBytes:&d range:NSMakeRange(shift,sizeof(d))];

    fprintf(stderr, "r%f, g%f, b%f, a%f \n", a,b,c,d );
}

这本来可以写得短得多,但是为了清楚起见,并减少了误导性内容的使用

也许这对某人有帮助