简体   繁体   中英

How to encode/decode a CFUUIDRef in Objective-C

I want to have a GUID in my objective-c model to act as a unique id. My problem is how to save the CFUUIDRef with my NSCoder as its not a an Object type.

I keep playing around with the following lines to encode/decode but I can't seem to find any good examples of how to save struct types in objective-c (all of my NSObject types are encoding/decoding fine).

eg for encoding I am trying (which I think looks good?):

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

and for decoding which is where I get more stuck:

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

I gt an error "conversion to a non-scaler type" above - I've tried several incarnations from bits of code I've seen on the web. Can anyone point me in the right direction? Tim

在容易(但有点更低效的)的方法是将其存储为一个NSStringCFString使用) CFUUIDCreateString ,并恢复与所述UUID CFUUIDCreateFromString

The problem with your code is the last line of the decoding, "bytes" is a pointer to a CFUUIDBytes struct and you're trying to cast it as if it is the CFUUIDBytes struct itself, which is not correct and is correctly detected by the compiler. Try changing the last line to:

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

The idea here is that you cast "bytes" to be a pointer to CFUUIDBytes (inner brackets) and then dereference the casted pointer (outer brackets). The outer brackets are not strictly necessary but I use them to make the expression clearer.

Based on the answers given, I tried the casting approach given by Eyal and also the NSData approach suggested by Rob, and I thought that the latter seemed clearer, although I am interested in what others think.

I ended up with the following:

- (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);
        }
    }
  }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM