如何使用initwithCoder和encodewithCoder来获取指针的值

时间:2014-06-17 18:57:46

标签: objective-c pointers nscoding

看来我的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和一个长度,但不是我想用字节解码的实际数据。

当我的对象只包含第一个字符和长度时,有人可以帮我理解如何以字节为单位对数据进行编码和解码吗?

1 个答案:

答案 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提示,他们在文档中找到了关于返回缓冲区临时生命周期的(相当隐藏的)信息。