【问题标题】:Encoding/decoding doubles with NSCodingNSCoding 使编码/解码加倍
【发布时间】:2012-01-07 21:54:25
【问题描述】:

如何将-[NSCoder encodeBytes:length:]-[NSCoder decodeBytesWithReturnedLength:] 与double 一起使用?

我有一个符合 NSCoding 且具有两个 double 属性的对象,目前正在使用 NSNumber 对值进行编码/解码:

- (id)initWithCoder:(NSCoder *)decoder
{
  if (!(self = [super init]))
    return nil;

  latitude = [(NSNumber *)[decoder decodeObject] doubleValue];
  longitude = [(NSNumber *)[decoder decodeObject] doubleValue];

  return self;
}

- (void)encodeWithCoder:(NSCoder *)coder
{
  [coder encodeObject:[NSNumber numberWithDouble:latitude]];
  [coder encodeObject:[NSNumber numberWithDouble:longitude]];
}

但是,这给了我无法接受的性能(用我的测试数据解码需要 6 秒,这比生产数据小得多)。

如果我使用密钥,我可以使用-encodeDouble:forKey:,但我没有使用密钥(它们很慢),并且与 Mac OS X 不同,iOS 上没有 -encodeDouble: 方法。

所以,我需要使用encodeBytes:length:decodeBytesWithReturnedLength:,但是我的C 能力非常有限。我不确定如何在void *double 之间进行转换。

【问题讨论】:

  • 解决这个问题后的一点反馈。更改为双精度并没有带来任何明显的性能改进,但它确实将存档的文件大小减少了大约 20%。
  • 等等,你为什么不直接使用encodeDouble: / decodeDouble:
  • 这两个只有现有的 Cocoa。它们在 UIKit 中不存在。由于某种原因,UIKit 只有encodeDouble:forKey:

标签: objective-c ios double nscoding


【解决方案1】:
[coder encodeBytes:(void *)&latitude length:sizeof latitude];

NSUInteger length;
latitude = *(double *)[coder decodeBytesWithReturnedLength:&length];

您也许可以通过NULL 而不是&length

【讨论】:

  • 谢谢。顺便说一句,我测试了为 length 传递 NULL 并且它确实有效。
【解决方案2】:

您应该只需要执行以下操作:

[coder encodeBytes:(void *)&latitude length:sizeof(double)];

然后:

double latitude = *(double *)([coder decodeBytesWithReturnedLength:NULL]);

更新:将 NULL 传递给解码

【讨论】:

  • 由于decodeBytesWithReturnedLength:NSUInteger* 作为其参数,因此这是行不通的。
  • 由于decodeBytesWithReturnedLength: 返回一个void*,如果不先将其转换为其他类型(大概是double*),就无法取消引用它。
  • 再次欢呼 :) 这就是我尝试一次做太多事情的结果
  • 谢谢!注意:由于我没有对len 做任何事情,因此我测试了证明 NULL 并且它似乎有效。也许更新你的答案?
【解决方案3】:
    [encoder encodeDouble:lat forKey:@"latitude"];
    [encoder encodeDouble:lng forKey:@"longitude"];

    double lat = [decoder decodeDoubleForKey:@"latitude"];
    double lng = [decoder decodeDoubleForKey:@"longitude"];

【讨论】:

  • 我不知道我在搜索文档时怎么错过了这个!谢谢伙计,我正在更改已接受的答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-22
  • 1970-01-01
  • 1970-01-01
  • 2015-12-04
相关资源
最近更新 更多