开发者

How to encode/decode a CFUUIDRef in Objective-C

开发者 https://www.devze.com 2022-12-19 06:09 出处:网络
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 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).

e.g. for encoding I am trying (which I think looks good?):

CFUUIDBytes bytes = CFUUIDGetUUIDBytes(uuid);
eencoder encodeBytes: &bytes length: sizeo开发者_运维知识库f(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


The easier (but a bit more inefficient) way is to store it as an NSString (CFString) using CFUUIDCreateString, and recover the UUID with 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);
        }
    }
  }
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号