Obj-C Как конвертировать NSData в массив целых? - PullRequest
7 голосов
/ 01 февраля 2011

У меня есть элемент NSData, который содержит кучу целых.Как я могу получить их в NSArray?

Структура памяти в NSData имеет 32-битный тип int в порядке с прямым порядком байтов, один за другим.

Извините заосновной вопрос, но все еще изучаю obj-c способ делать вещи :)

Ответы [ 4 ]

13 голосов
/ 01 февраля 2011

Вы можете использовать функции, определенные в OSByteOrder.h, для работы с порядком байтов. Помимо этой причуды, это на самом деле просто вопрос захвата байтового буфера и итерации по нему.

// returns an NSArray containing NSNumbers from an NSData
// the NSData contains a series of 32-bit little-endian ints
NSArray *arrayFromData(NSData *data) {
    void *bytes = [data bytes];
    NSMutableArray *ary = [NSMutableArray array];
    for (NSUInteger i = 0; i < [data length]; i += sizeof(int32_t)) {
        int32_t elem = OSReadLittleInt32(bytes, i);
        [ary addObject:[NSNumber numberWithInt:elem]];
    }
    return ary;
}
2 голосов
/ 01 февраля 2011

Похоже, есть более чистые способы сделать то, что вы пытаетесь сделать, но это должно сработать:

NSData *data = ...; // Initialized earlier
int *values = [data bytes], cnt = [data length]/sizeof(int);
for (int i = 0; i < cnt; ++i)
  NSLog(@"%d\n", values[i]);
1 голос
/ 01 февраля 2011

Этот ответ очень похож на другие ответы выше, но я посчитал полезным поиграть с приведением байтов NSData обратно в массив int32_t []. Этот код корректно работает на процессоре с прямым порядком байтов (в моем случае x64), но в случае с байтовым порядком байтов (PPC) он будет совершенно неверным, поскольку байтовое представление будет иметь байтовый порядок.

int32_t raw_data[] = {0,1,2,3,4,5,6,7,8,9,10};
printf("raw_data has %d elements\n", sizeof(raw_data)/sizeof(*raw_data));
NSData *data = [NSData dataWithBytes:(void*)raw_data length:sizeof(raw_data)];
printf("data has %d bytes\n", [data length]);
int32_t *int_data_out = (int32_t*) [data bytes];
for (int i=0; i<[data length]/4; ++i)
    printf("int %d = %d\n", i, int_data_out[i]);
[data release];
0 голосов
/ 01 февраля 2011

Одно из возможных решений ниже. Чтобы принять во внимание порядок байтов, ищите Базовую ссылку на байты в наборе документов XCode (вы, вероятно, будете использовать EndianS32_LtoN (от 32-битного младшего байта к порядку байтов)).

int mem[]= {0x01, 0x02, 0x03, 0x04, 0xff};


NSData * data = [NSData dataWithBytes:mem length:sizeof(mem)*sizeof(int)];
NSMutableArray * ar = [NSMutableArray arrayWithCapacity:10];

/* read ints out of the data and add them to the array, one at a time */
int idx=0;
for(;idx<[data length]/sizeof(int);idx+=sizeof(int))
       [ar addObject:[NSNumber numberWithInt:*(int *)([data bytes] + idx)]];

NSLog(@"Array:%@", ar);
...