我可以在另一个 NSData 中存档 NSData 对象而不损坏数据吗?

Posted

技术标签:

【中文标题】我可以在另一个 NSData 中存档 NSData 对象而不损坏数据吗?【英文标题】:Can I Archive NSData objects inside another NSData without corrupting data? 【发布时间】:2013-03-02 23:08:38 【问题描述】:

我有两个 NSData 对象要存储在第三个 NSData 对象中。我的想法是,当我稍后解码较大的对象时,我想让它变得容易,以便彼此独立地获取两个较小的对象,而不用担心它们的相对大小或数据类型。

似乎最好的方法是使用 NSKeyedArchiver 在较大的 NSData 对象中创建一种根级键值结构,我可以在其中将两个较小的对象存储在单独的键中。这就是我在这里尝试做的:

NSData *data1Before = [@"abcdefgh" dataUsingEncoding:NSUTF8StringEncoding];
NSData *data2Before = [@"ijklmnop" dataUsingEncoding:NSUTF8StringEncoding];

NSMutableData *allData = [[NSMutableData alloc] init];
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:allData];
[archiver encodeObject:data1Before forKey:@"key1"];
[archiver encodeObject:data2Before forKey:@"key2"];
[archiver finishEncoding];

NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:allData];
NSData *data1After = [unarchiver decodeObjectForKey:@"key1"];
NSData *data2After = [unarchiver decodeObjectForKey:@"key2"];
[unarchiver finishDecoding];

NSString *string1After = [NSString stringWithUTF8String:[data1After bytes]];
NSString *string2After = [NSString stringWithUTF8String:[data2After bytes]];

NSLog(@"after1: %@",string1After);
NSLog(@"after2: %@",string2After);

问题是,当你一遍又一遍地运行这段代码时,你会从 NSLog 语句中得到各种不同的结果——有时特殊字符会附加到字符串的末尾,有时它们只是 NULL。

看来这种损坏与我正在使用的这种“双重编码”过程有关。当我修改代码以便 NSKeyedArchiver 直接在 NSStrings 上而不是在 NSData 对象上调用 encodeObject 时,我以后可以使用 decodeObjectForKey 并毫无问题地获取这些字符串 - 完全没有损坏。

有没有比使用 NSKeyedArchiver 更好的方法呢?还是我用错了?

【问题讨论】:

为什么要将字符串转换为数据?为什么不直接归档原始字符串?这将节省大量不必要的转换。 也许这个:[NSString stringWithUTF8String:[data1After bytes]]; 应该是:[[NSString alloc] initWithData:data1After encoding: NSUTF8StringEncoding]; @rmaddy #1:因为我必须在 NSData 对象中支持各种不同的数据集——而不仅仅是字符串。 #2:太好了!那解决了,谢谢!如果您将其发布为答案,我很乐意将其标记为解决方案。 【参考方案1】:

感谢 rmaddy 上面的回答——我只需要替换这个:

[NSString stringWithUTF8String:[data1After bytes]];

用这个:

[[NSString alloc] initWithData:data1After encoding: NSUTF8StringEncoding];

然后就解决了。

【讨论】:

请注意,这在NSString stringWithUTFString:... 不适用的地方有效——对于其他任何人来说,他们的头发都拉出来了......

以上是关于我可以在另一个 NSData 中存档 NSData 对象而不损坏数据吗?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 iOS 中将 NSData 变量转换为 NSInteger 变量

我可以创建一个引用内存中 NSData 的 NSURL 吗?

从 NSData 中查找视频类型

NSData/UIImage 到字符串

将 NSData 转换为 SecKeyRef

如何用 NSMutableArray 初始化 NSData 对象?