如果我将10Mb的数据放入其中然后将长度设置为零,那么使用1Mb容量初始化的NSMutableData会发生什么?它是否将容量缩减到初始值或保持不变(此时为10Mb)?
所以基本上我需要将整个数据对象缩小到初始容量,我不需要内部数据,但我不喜欢为此重新创建对象的想法,有没有办法实现呢?
答案 0 :(得分:3)
Apple不会保证此处的任何特定行为,但就我的经验而言,NSMutableData只会“增长”容量,它永远不会缩小。这意味着,如果您创建一个NSMutableData对象,向其添加10 MB数据,然后将其长度设置为0,实际上它仍将在内部分配10 MB的存储空间,它只会为其长度属性报告0。这是您可以使用NSMutableArray监视的类似行为,它与您可以在其他编程语言中监视的行为相同(例如,大多数Java标准对象都以这种方式运行)。
原因很简单:内存分配是一项昂贵的操作。不是非常昂贵,但它通常不是O(1)。只改变长度是一个非常快速的O(1)操作,因为它只需要改变一个实例变量。如果减少长度并且NSMutableArray缩小其内部存储,则必须执行重新分配,并且下次添加数据时,必须再次执行重新分配。这意味着如果你想尽可能少地使用内存,你不应该将长度设置回零,而是创建一个新的NSMutableData并释放旧的NSMutableData。只有这样才能保证尽可能减少内存使用量。缺点是下次为它添加内存时,由于需要重新分配,因此操作会更加昂贵。这是通常的CPU与内存之间的权衡。允许一段代码使用的内存越少,它通常消耗的内存就越多;另一方面,允许一段代码使用的内存越多,它可以节省的CPU时间就越多。
由于Mac通常有足够的内存,因此不会为可变数据对象重新分配其内部内存而付出代价,至少如果这只能节省几MB,则无法获得回报。另一方面,如果将500 MB数据对象缩减为零,它可能真的会重新分配。由于没有保证行为,NSMutableData在iOS上的行为可能完全不同,因为在iOS设备上,内存是一个受限制的资源。
答案 1 :(得分:1)
文档状态:
setLength: 将可变数据对象扩展或截断为给定长度。
- (void)setLength:(NSUInteger)length
参数 长度 接收器的新长度。
讨论 如果扩展了可变数据对象,则用零填充附加字节。
状况 适用于Mac OS X v10.0及更高版本。 也可以看看 - increaseLengthBy: 相关示例代码 LSMSmartCategorizer 宣告进入 NSData.h
所以我会将“截断”变为0尺寸 但是要确保你可以进行一些测试并检查仪器中的堆痕迹。