如何在Objective-C中编码/解码CFUUIDRef
我想在objective-c模型中使用GUID作为唯一id。我的问题是如何将CFUUIDRef与NSCoder一起保存为非对象类型 我一直在玩弄下面几行代码来进行编码/解码,但我似乎找不到任何关于如何在objective-c中保存结构类型的好例子(我所有的NSObject类型都可以进行编码/解码) e、 g.对于编码,我正在尝试(我认为这看起来不错?) 对于解码,我会更加困惑:如何在Objective-C中编码/解码CFUUIDRef,objective-c,guid,Objective C,Guid,我想在objective-c模型中使用GUID作为唯一id。我的问题是如何将CFUUIDRef与NSCoder一起保存为非对象类型 我一直在玩弄下面几行代码来进行编码/解码,但我似乎找不到任何关于如何在objective-c中保存结构类型的好例子(我所有的NSObject类型都可以进行编码/解码) e、 g.对于编码,我正在尝试(我认为这看起来不错?) 对于解码,我会更加困惑: NSUInteger blockSize; const void* bytes = [decoder decodeBy
NSUInteger blockSize;
const void* bytes = [decoder decodeBytesForKey: kFieldCreatedKey returnedLength:&blockSize];
if(blockSize > 0) {
uuid = CFUUIDCreateFromUUIDBytes(NULL, (CFUUIDBytes)bytes);
}
我在上面的“转换为非定标器类型”中遇到了一个错误——我已经尝试了从我在web上看到的代码中的一些具体化。谁能给我指出正确的方向吗?
Tim更简单(但效率稍低)的方法是使用
CFUUIDCreateString
将其存储为NSString
(CFString
)并使用CFUUIDCreateFromString
恢复UUID。代码的问题是解码的最后一行,“字节”是指向CFUUIDBytes结构的指针,您试图将其强制转换为CFUUIDBytes结构本身,这是不正确的,并且被编译器正确检测到。尝试将最后一行更改为:
uuid = CFUUIDCreateFromUUIDBytes(NULL, *((CFUUIDBytes*)bytes));
这里的想法是将“bytes”强制转换为指向CFUUIDBytes(内括号)的指针,然后取消引用强制转换的指针(外括号)。外括号不是绝对必要的,但我使用它们使表达更清晰。根据给出的答案,我尝试了Eyal给出的铸造方法和Rob建议的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);
}
}
}
或者您可以通过使用
cfuuidgetuuibytes
获取字节,并使用dataWithBytes:length:
方法NSData
将其存储为NSData
。实际上,NSData路由是我已经忘记的,我认为它看起来很有前途。ThanksI还应该补充一点,我不想使用CFString选项,因为我应该能够直接存储UUID对象(如前所述,比转换字符串更有效)@TimM:在这种情况下使用Eyal的解决方案。除非您经常对UUID进行解压缩/归档,否则效率并不重要。事实上,取消/归档可能比将UUID从/转换为字符串花费更多的时间。这无疑让我走得更远——我发现了我的编码示例中的一个问题,我没有设置密钥——这就引发了我如何传递UUID字节的问题。以下是您的行的对称保存:[encoder encodeBytes:(void*)和bytes length:sizeof(bytes)forKey:kFieldCreatedKey];上述方法似乎可行,但感觉更像是C风格而不是objective-C(尽管非常感谢你让我走上正轨)。我认为关于使用NSData的评论可能会给出一个较低级别的解决方案。使用NSData不会给出更高(或低)级别的解决方案,因为在这两种情况下,您都使用了cfuuidCreateFromuuiBytes和cfuuidGetuuiBytes。低/高级别的术语在这里是不相关的。两种解决方案之间的区别在于对获取或设置为uuid的字节进行编码/解码的方法。两者都是有效的(尽管使用“encodeBytes”可能意味着更少的代码)。这里重要的一点是确保您理解最初发布的代码失败的原因以及修复代码工作的原因。同意-我不使用CFString方法的原因是我想了解底层细节应该如何工作(您的回答表明了这一点)。我将发布完整的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);
}
}
}