看来我的initwithCoder和encodewithCoder正在运行,但我做了些蠢事。
为简单起见,我要显示我的问题的相关代码。我有几个从指针和长度获取NSData的对象,因此值存储为const char *和length。
以下是界面:
@interface IDImage : NSObject <NSCoding>
@property (nonatomic) const char *templateData;
@property (nonatomic) NSUInteger templateSize;
- (void)encodeWithCoder:(NSCoder *)coder;
- (id)initWithCoder:(NSCoder *)coder;
以下是实施:
- (void)encodeWithCoder:(NSCoder *)encoder {
[encoder encodeBytes:(const unsigned char*)self.templateData length:self.templateSize forKey:@"templateData"];
[encoder encodeInteger:self.templateSize forKey:@"templateSize"];
}
- (id)initWithCoder:(NSCoder *)decoder {
NSUInteger length = 0;
self = [super init];
if (self) {
self.templateData = (const char *)[decoder decodeBytesForKey:@"templateData" returnedLength:&length];
self.templateSize = [decoder decodeIntegerForKey:@"templateSize"];
}
return self;
}
我想我写出了编码的字节(假设NSCoder正在写出第一个字符一直到结尾,即templateSize)。但是当我尝试解码时,我检索一个指向templateData的指针。我如何获得价值?如果我有值,它是否只包含第一个字符?意思是我有一个char和一个长度,但不是我想用字节解码的实际数据。
当我的对象只包含第一个字符和长度时,有人可以帮我理解如何以字节为单位对数据进行编码和解码吗?
答案 0 :(得分:1)
如果你查看相关方法decodeBytesWithReturnedLength:
的文档,它会说:
如果您需要超出当前@autoreleasepool范围的字节 阻止,你必须复制它们。
我认为decodeBytesForKey:returnedLength:
遵循相同的规则。所以你的代码应该是这样的:
- (id)initWithCoder:(NSCoder *)decoder
{
NSUInteger length = 0;
self = [super init];
if (self)
{
void* temp = decoder decodeBytesForKey:@"templateData" returnedLength:&length];
void *bytes = malloc(length);
memcpy(bytes, temp, length);
self.templateData = bytes;
self.templateSize = [decoder decodeIntegerForKey:@"templateSize"];
}
return self;
}
然后将这样的代码添加到你的dealloc:
- (void) dealloc;
{
if (_templateData)
free(_templateData);
)
向@nil提示,他们在文档中找到了关于返回缓冲区临时生命周期的(相当隐藏的)信息。