Структура для NSData между Mac и iOS

Я работал над этой проблемой некоторое время, у меня есть приложение, работающее на Mac, оно имеет координаты данных, которые хранятся в такой структуре:

struct xyz {
  float x;
  float y;
  float z;
};

struct xy {
  float x;
  float y;
};

struct object {
  struct xyz *myXYZ;
  struct xy *myXY;
};

Это все работает как положено, затем я добавляю структуру в NSData вот так:

struct object anInitialTestStruct;
NSMutableData *myTestDataOut = [NSMutableData dataWithBytes:&anInitialTestStruct length:64 freeWhenDone:NO];
BOOL good = [myTestDataOut writeToFile:[NSString stringWithFormat:@"%@/filename.dat", docsDirectory] atomically:YES];

Это работает, как и ожидалось, я получаю файл и похоже, что в нем есть данные (для справки я использовал указатели и malloc для anInitialTestStruct, но все еще не получаю желаемый результат)

Теперь на iphone я копирую файл в проект и делаю это:

NSString *filePath = [[NSBundle mainBundle] pathForResource:@"filename" ofType:@"dat"];
NSData *myVecNSData = [[NSData alloc] initWithContentsOfFile:filePath options:NSDataReadingUncached error:&error];
if ( error ) {
    NSLog(@"%@", error);
}

Я не получаю правильные данные обратно. Интересно, если я побегу initWithContents метод на Mac и читать файл там, кажется, все в порядке.

Так что я думаю, что в iphone / mac есть что-то другое в отношении файловой системы... Я пытался кодировать данные, используя NSKeyedArchiver, но я получаю исключение о том, что "непонятный архив....."

2 ответа

Решение

В случае вашей "объектной" структуры вы должны хранить структуры "xy" и "xyz" отдельно, например, в словаре:

    struct object anInitialTestStruct;
    NSDictionary *structureDataAsDictionary = [NSDictionary dictionaryWithObjectsAndKeys:
                                     [NSMutableData dataWithBytes:anInitialTestStruct.myXY length:sizeof(xy)], @"xy key",
                                     [NSMutableData dataWithBytes:anInitialTestStruct.myXYZ length:sizeof(xyz)], @"xyz key",
                                     nil];
    NSData *myTestDataOut = [NSKeyedArchiver archivedDataWithRootObject:structureDataAsDictionary];
    BOOL good = [myTestDataOut writeToFile:[NSString stringWithFormat:@"%@/filename.dat", docsDirectory] atomically:YES];

и декодирование примерно так:

    struct object anInitialTestStruct;
    NSString *filePath = [[NSBundle mainBundle] pathForResource:@"filename" ofType:@"dat"];
    NSData *myVecNSData = [[NSData alloc] initWithContentsOfFile:filePath options:NSDataReadingUncached error:&error];
    if ( error ) {
        NSLog(@"%@", error);
    }
    // retrieving dictionary from NSData
    NSDictionary *structureDataAsDictionary = [NSKeyedUnarchiver unarchiveObjectWithData:myVecNSData];
    // allocating memory for myXY and myXYZ fields
    anInitialTestStruct.myXY = (xy*)malloc(sizeof(xy));
    if (anInitialTestStruct.myXY == NULL) {
        // error handling
    }
    anInitialTestStruct.myXYZ = (xyz*)malloc(sizeof(xyz));
    if (anInitialTestStruct.myXYZ == NULL) {
        // error handling
    }
    // filling myXY and myXYZ fields with read data
    [[structureDataAsDictionary objectForKey:@"xy key"] getBytes:anInitialTestStruct.myXY];
    [[structureDataAsDictionary objectForKey:@"xyz key"] getBytes:anInitialTestStruct.myXYZ];

Вы могли бы иметь достоверную кодировку ваших указателей, смотрите здесь

"указатели

Вы не можете закодировать указатель и получить что-то полезное во время декодирования. Вы должны закодировать информацию, на которую указывает указатель. Это верно и для неключевого кодирования. ..."

Другие вопросы по тегам