Как кодировать / декодировать CFUUIDRef в Objective-C - PullRequest
3 голосов
/ 08 февраля 2010

Я хочу, чтобы GUID в моей модели target-c действовал как уникальный идентификатор. Моя проблема заключается в том, как сохранить CFUUIDRef с моим NSCoder, поскольку это не тип объекта.

Я продолжаю играть со следующими строками для кодирования / декодирования, но не могу найти хороших примеров того, как сохранять типы структур в target-c (все мои типы NSObject хорошо кодируются / декодируются).

например. для кодирования я пытаюсь (что я думаю, выглядит хорошо?):

CFUUIDBytes bytes = CFUUIDGetUUIDBytes(uuid);
eencoder encodeBytes: &bytes length: sizeof(bytes)];

и для декодирования, где я застреваю:

NSUInteger blockSize;
const void* bytes = [decoder decodeBytesForKey: kFieldCreatedKey returnedLength:&blockSize];
if(blockSize > 0) {
     uuid = CFUUIDCreateFromUUIDBytes(NULL, (CFUUIDBytes)bytes);
}

Я получил сообщение об ошибке "преобразование в тип без масштабирования" выше - я пробовал несколько воплощений из фрагментов кода, которые я видел в Интернете. Может кто-то указать мне верное направление? Тим

Ответы [ 3 ]

2 голосов
/ 08 февраля 2010

Проблема с вашим кодом - последняя строка декодирования, "байты" - это указатель на структуру CFUUIDBytes, и вы пытаетесь привести ее так, как если бы она была самой структурой CFUUIDBytes, что неверно и правильно обнаружен компилятором. Попробуйте изменить последнюю строку на:

uuid = CFUUIDCreateFromUUIDBytes(NULL, *((CFUUIDBytes*)bytes));

Идея в том, что вы приводите "байты" в качестве указателя на CFUUIDBytes (внутренние скобки), а затем разыменовываете приведенный указатель (внешние скобки). Внешние скобки не являются строго необходимыми, но я использую их, чтобы сделать выражение более понятным.

2 голосов
/ 08 февраля 2010

Более простой (но немного более неэффективный) способ - сохранить его как NSString (CFString) с помощью CFUUIDCreateString и восстановить UUID с помощью CFUUIDCreateFromString.

0 голосов
/ 10 февраля 2010

Основываясь на полученных ответах, я попробовал подход к кастингу, предложенный Eyal, а также подход NSData, предложенный Робом, и подумал, что последний показался более ясным, хотя мне интересно, что думают другие.

Я получил следующее:

- (void)encodeWithCoder:(NSCoder *)encoder {  
    // other fields encoded here
    CFUUIDBytes bytes = CFUUIDGetUUIDBytes(uuid);
    NSData* data  = [NSData dataWithBytes: &bytes length: sizeof(bytes)];
    [encoder encodeObject: data forKey: kFieldUUIDKey];
}

- (id)initWithCoder:(NSCoder *)decoder {
    if (self = [super init]) { 
        // other fields unencoded here
        NSData* data = [decoder decodeObjectForKey: kFieldUUIDKey];
        if(data) {
          CFUUIDBytes uuidBytes;
          [data getBytes: &uuidBytes];
          uuid = CFUUIDCreateFromUUIDBytes(NULL,uuidBytes);
    } else {
          uuid = CFUUIDCreate(NULL);
        }
    }
  }
...