NSMutableData 长度变化时的容量

发布于 2024-12-11 14:06:15 字数 188 浏览 2 评论 0原文

如果我将 10Mb 的数据放入 NSMutableData 中,然后将长度设置为零,那么初始化为 1Mb 容量的 NSMutableData 会发生什么情况?是否会将容量缩减回初始值或保持原样(目前为 10Mb)?

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

What happens with NSMutableData initialized with 1Mb capacity if I put 10Mb of data into it and then set length to zero? Does it shrink capacity back to initial value or leaves it as is (10Mb at the moment)?

So basically I need to shrink whole data object to initial capacity and I don't need data inside, but I don't like the idea to re-create object for that, is there any way to achieve that?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

來不及說愛妳 2024-12-18 14:06:15

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 设备上内存是一种更受限制的资源。

Apple does not guarantee any specific behavior here, however as far as my experience goes, a NSMutableData will only "grow" in capacity, it will never shrink. That means, if you create a NSMutableData object, add 10 MB of data to it and then set its length to 0, it will in fact still internally have a storage space of 10 MB allocated, it will just report 0 for its length property. This is similar behavior you can monitor with NSMutableArray and it's the same behavior you can monitor in other programming languages (e.g. most Java standard objects behave that way).

The reason for that is simple: Memory allocation is an expensive operation. Not horribly expensive, but it's usually not O(1). Only changing the length is a very fast O(1) operation, since it only has to alter an instance variable. If you decrease the length and NSMutableArray shrinks its internal storage, it had to perform a reallocation and next time you add data, it has to perform a reallocation again. That means if you want to use as little memory as possible, you should not set the length back to zero, but instead create a new NSMutableData and release the old one. Only that will guarantee you smallest memory usage possible. The downside is that next time you add memory to it, it will be a much more expensive operation since a reallocation is necessary. It's the usual CPU vs memory trade off. The less memory you allow a piece of code to use, the more memory it will usually consume; on the other hand, the more memory you allow a piece of code to use, the more CPU time it can save.

Since Macs have usually plenty of memory, it does not pay off for a mutable data object to reallocate its internal memory, at least not if this would only save a couple of MBs. On the other hand, it might really reallocate if you shrink a 500 MB data object back to zero. And as no behavior is guaranteed, NSMutableData might behave quite differently on iOS because on iOS devices memory is a much more restricted resource.

超可爱的懒熊 2024-12-18 14:06:15

文档状态:

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

- (void)setLength:(NSUInteger)length

参数
长度
接收器的新长度。

讨论
如果扩展可变数据对象,则附加字节将用零填充。

可用性
适用于 Mac OS X v10.0 及更高版本。
参见
– 增加长度:
相关示例代码
LSM智能分类器
申报于
NSData.h


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

The documentation state :

setLength:
Extends or truncates a mutable data object to a given length.

- (void)setLength:(NSUInteger)length

Parameters
length
The new length for the receiver.

Discussion
If the mutable data object is extended, the additional bytes are filled with zeros.

Availability
Available in Mac OS X v10.0 and later.
See Also
– increaseLengthBy:
Related Sample Code
LSMSmartCategorizer
Declared In
NSData.h


So I would go for "truncates" to a 0 size.
But to be sure you can make a little test and check the heap trace in instrument.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文