2011-09-07 39 views
17

Tôi đã một đối tượng NSData, chiều dài là 4 byte .These bốn byte tôi chiết xuất từ ​​một đối tượng NSData sử dụng,Chuyển đổi NSData để int

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

câu hỏi đầu tiên của tôi là, sẽ tuyên bố trên cung cấp cho tôi bốn byte đầu tiên của dữ liệu hoàn chỉnh.

Nếu có, thì cách chuyển đổi tất cả các byte này thành int tương đương.

+0

Tùy thuộc vào nguồn gốc của dữ liệu, bạn có thể cần xem xét tính cuối của dữ liệu.Nếu dữ liệu được tạo ra và chỉ chuyển giao xung quanh trong mã của bạn thì bạn sẽ ổn, nếu không bạn cần phải nhận thức được chút/lớn endian. – Joe

+0

có thể trùng lặp của [Chuyển đổi NSdata thành byte và sau đó chuyển đổi n byte đầu tiên thành int] (http://stackoverflow.com/questions/7330436/converting-nsdata-to-bytes-then-converting-the-first-n- byte-to-int) –

Trả lời

30

là 268.566.528 giá trị mà bạn mong đợi hoặc có lẽ bạn mong đợi 528? Nếu giá trị chính xác là 528 thì thứ tự byte là lớn-endian nhưng cpu là ít-endian, các byte cần phải được đảo ngược.

Vì vậy, nếu giá trị đúng nên 528 thì:

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

Cũng lưu ý rằng mạng trật tự giữa các ý kiến ​​lớn về cuối nhỏ.

22

Đó tuyên bố sẽ cung cấp cho bạn 16 byte dữ liệu đầu tiên, chứ không phải 4. Để có được 4 byte đầu tiên bạn cần phải sửa đổi tuyên bố của bạn để:

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

Để đọc dữ liệu từ Object NSData đến một số nguyên bạn có thể làm điều gì đó như:

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

Bạn không cần nhận 4 byte đầu tiên nếu bạn chỉ chuyển đổi thành số nguyên. Bạn có thể thực hiện việc này trực tiếp từ hai dòng ở trên và máy thu completeData

+0

Giải pháp hoàn hảo, dữ liệu này sẽ là LSB (sẵn sàng cho iOS) trong một bước –

11

Không, bạn sẽ nhận được 16 byte dữ liệu vì phạm vi từ offset 0 và sau đó là 16 byte.

Nếu bạn đã có một trường hợp NSData với 4 byte sau đó bạn có thể làm một kiểu đơn giản đúc như thế này:

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

Dữ liệu bốn byte <00000210> int value: 268566528 Tôi nhận được kết quả int sau cho dữ liệu này. Có phải này ........ chỉ cần tự hỏi. –

+0

@Pranav - Phụ thuộc vào thứ tự byte của dữ liệu trong cá thể 'NSData' của bạn là gì? – PeyloW

+0

Điều này hoạt động hoàn hảo. – rjgonzo

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]; 
+0

Giải pháp tốt nhất cho đến nay –

4

Lưu trữ số nguyên iOS LSB (byte quan trọng thấp nhất) trong byte đầu tiên và MSB trong byte cuối cùng. Tôi có thói quen chuyển đổi để kiểm tra tất cả những điều đó. kiểm tra ở đây,

thử nghiệm ...

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; 
} 
+0

Tuyệt vời! Đặc biệt nếu ai đó đang tìm kiếm giải pháp đa nền tảng. –

1

Nó phụ thuộc vào các ký hiệu Endian của dữ liệu bạn muốn chuyển đổi, liên quan đến ký hiệu thiết bị Endian của bạn. wiki on Endianness

Để giữ cho nó đơn giản, bạn cần phải kiểm tra không hai phương pháp

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

hoặc

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

Và kiểm tra mà người ta có ý nghĩa hơn khi bạn phân tích dữ liệu.

Các vấn đề liên quan