如何 initwithCoder 和 encodewithCoder 获取指针的值
Posted
技术标签:
【中文标题】如何 initwithCoder 和 encodewithCoder 获取指针的值【英文标题】:How to initwithCoder and encodewithCoder to get value of pointer 【发布时间】:2014-06-17 18:57:46 【问题描述】:看来我的 initwithCoder 和 encodewithCoder 工作正常,但我在做一些愚蠢的事情。
为简单起见,我将显示我的问题的相关代码。我有几个从指针和长度获取 NSData 的对象,因此这些值被存储为 const char * 和长度。
界面如下:
@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 的指针。我如何获得价值?如果我有这个值,它会只包含第一个字符吗?这意味着我有一个字符和一个长度,但没有我打算以字节为单位解码的实际数据。
当我的对象只包含第一个字符和长度时,有人可以帮我理解如何以字节为单位编码和解码数据吗?
【问题讨论】:
另外,我逐步检查了我的 initWithCoder 和 encodeWithCoder 并且值相同(如预期的那样)但在调用代码中值不同: templateToRead = [NSKeyedUnarchiver unarchiveObjectWithFile:[documentsDirectory stringByAppendingPathComponent:item]] ; 【参考方案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,他在文档中发现了(相当隐藏的)关于返回缓冲区临时寿命的信息。
【讨论】:
是的,在你们两个之间,我终于成功了。 请注意,如果您的对象没有 dealloc 方法,则必须添加一个并确保它释放内存缓冲区。否则会导致内存泄漏。以上是关于如何 initwithCoder 和 encodewithCoder 获取指针的值的主要内容,如果未能解决你的问题,请参考以下文章
如何在 UIView 的子类中同时覆盖 initWithFrame: 和 initWithCoder:?
initWithCoder:被 nib 和 NSCoding 调用!
当覆盖 initWithCoder 时,总是需要调用 [super initWithCoder: coder]
方法 Swizzle encodeWithCoder/initWithCoder