0

如果我将 10Mb 的数据放入其中,然后将长度设置为零,那么使用 1Mb 容量初始化的 NSMutableData 会发生什么?它将容量缩小到初始值还是保持原样(目前为 10Mb)?

所以基本上我需要将整个数据对象缩小到初始容量,并且我不需要内部数据,但我不喜欢为此重新创建对象的想法,有什么办法可以实现吗?

4

2 回答 2

3

Apple 不保证此处的任何特定行为,但就我的经验而言, NSMutableData 只会“增长”容量,永远不会缩小。这意味着,如果您创建一个 NSMutableData 对象,向其添加 10 MB 的数据,然后将其长度设置为 0,它实际上仍会在内部分配 10 MB 的存储空间,它只会报告其长度属性为 0。这与您可以使用 NSMutableArray 监控的行为相似,并且您可以在其他编程语言中监控相同的行为(例如,大多数 Java 标准对象的行为方式都是如此)。

原因很简单:内存分配是一项昂贵的操作。不是很贵,但通常不是 O(1)。只改变长度是一个非常快的 O(1) 操作,因为它只需要改变一个实例变量。如果减少长度并且 NSMutableArray 缩小其内部存储,它必须执行重新分配,下次添加数据时,它必须再次执行重新分配。这意味着如果您想使用尽可能少的内存,则不应将长度设置回零,而是创建一个新的 NSMutableData 并释放旧的。只有这样才能保证您尽可能减少内存使用量。缺点是下次您向其中添加内存时,由于需要重新分配,这将是一项更昂贵的操作。这是通常的 CPU 与内存权衡。您允许一段代码使用的内存越少,它通常消耗的内存就越多;另一方面,允许一段代码使用的内存越多,它可以节省的 CPU 时间就越多。

由于 Mac 通常有足够的内存,所以它不会为可变数据对象重新分配其内部内存带来回报,至少如果这只会节省几 MB 则不会。另一方面,如果将 500 MB 的数据对象缩小到零,它可能真的会重新分配。由于不能保证任何行为,NSMutableData 在 iOS 上的行为可能完全不同,因为在 iOS 设备上,内存是一种更受限制的资源。

于 2012-01-17T12:50:14.747 回答
1

文档状态:

setLength: 将可变数据对象扩展或截断到给定长度。

- (void)setLength:(NSUInteger)length

参数 length 接收器的新长度。

讨论 如果可变数据对象被扩展,额外的字节用零填充。

可用性 适用于 Mac OS X v10.0 及更高版本。另请参阅 – increaseLengthBy:在 NSData.h 中声明的相关示例代码 LSMSmartCategorizer


所以我会选择“截断”到 0 大小。
但是为了确保您可以进行一些测试并检查仪器中的堆跟踪。

于 2011-11-04T16:38:02.470 回答