保留计数 NSArray 与 NSMutableArray

发布于 2024-11-02 07:14:29 字数 244 浏览 2 评论 0 原文

带有代码示例的简短问题:

NSLog(@"%i", [[[NSArray alloc] init] retainCount]);
NSLog(@"%i", [[[NSMutableArray alloc] init] retainCount]);

输出:

2
1

为什么 NSArray 和 NSMutableArray 的保留计数不同?

Short Question with a code example:

NSLog(@"%i", [[[NSArray alloc] init] retainCount]);
NSLog(@"%i", [[[NSMutableArray alloc] init] retainCount]);

Output:

2
1

Why is the retainCount from the NSArray and NSMutableArray different?

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

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

发布评论

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

评论(2

桃气十足 2024-11-09 07:14:29

苹果之外没有人确切知道(但我确信很快就会有人声称他确切知道为什么会发生这种情况)。
也许发生这种情况是因为 iOS 很聪明,它重用了空的 NSArray。显然 [[NSArray alloc] init] 创建了一个没有实际用途的空数组。而且由于它是不可变的(即以后不能添加对象,并且它将永远为空),因此所有空 NSArrays 指针都可以引用同一个对象。

可变的不能重复使用,因为您可以向其中添加对象。


不要使用retainCount!

来自 苹果文档

重要:此方法通常对于调试内存管理问题没有任何价值。因为任意数量的框架对象可能保留了一个对象以保存对其的引用,而同时自动释放池可能在对象上保存任意数量的延迟释放,因此您不太可能从中获得有用的信息方法。

要了解必须遵守的内存管理基本规则,请阅读“内存管理规则”。要诊断内存管理问题,请使用合适的工具:

  • LLVM/Clang 静态分析器通常可以在运行程序之前发现内存管理问题.
  • Instruments 应用程序中的对象分配工具(请参阅 仪器用户指南)可以跟踪对象分配和销毁。
  • Shark(请参阅Shark 用户指南)还介绍了内存分配(以及程序的许多其他方面)。

Nobody outside of apple knows for sure (but I'm sure soon there will be somebody that claims he knows exactly why that happened).
Maybe this happens because iOS is smart and it reuses empty NSArrays. And obviously [[NSArray alloc] init] creates an empty array that is of no real use. And since it`s not mutable (ie you can't add objects later, and it will be empty forever) all empty NSArrays pointers can reference the same object.

The mutable one can't be reused because you can add objects to it.


Do not use retainCount!

From the apple documentation:

Important: This method is typically of no value in debugging memory management issues. Because any number of framework objects may have retained an object in order to hold references to it, while at the same time autorelease pools may be holding any number of deferred releases on an object, it is very unlikely that you can get useful information from this method.

To understand the fundamental rules of memory management that you must abide by, read “Memory Management Rules”. To diagnose memory management problems, use a suitable tool:

  • The LLVM/Clang Static analyzer can typically find memory management problems even before you run your program.
  • The Object Alloc instrument in the Instruments application (see Instruments User Guide) can track object allocation and destruction.
  • Shark (see Shark User Guide) also profiles memory allocations (amongst numerous other aspects of your program).
爱殇璃 2024-11-09 07:14:29

原因是 [[NSArray alloc] init] 无论调用多少次都会返回相同的对象。看一下这段代码:

NSArray *array1 = [[NSArray alloc] init];
NSArray *array2 = [[NSArray alloc] init];
NSArray *array3 = [[NSArray alloc] init];
NSLog(@"\narray1: %p\narray2: %p\narray3: %p",
      array1, array2, array3);

输出是:

array1: 0x10010cae0
array2: 0x10010cae0
array3: 0x10010cae0

这是有道理的,因为 NSArray 是不可变的,并且所有空数组都是相同的。看起来 NSArray 为此目的保留了一个空数组,因为 array1、array2 和 array3 指向的数组的保留计数是 4。

我不同意 @fluchtpunkt 的答案,但我认为可以肯定地说,我们确切地知道为什么会发生这种情况。我想你可能会说没有人确切知道为什么苹果选择以这种方式实现它,但这看起来确实是一个好主意。

The reason is that [[NSArray alloc] init] returns the same object no matter how many times you call it. Look at this code:

NSArray *array1 = [[NSArray alloc] init];
NSArray *array2 = [[NSArray alloc] init];
NSArray *array3 = [[NSArray alloc] init];
NSLog(@"\narray1: %p\narray2: %p\narray3: %p",
      array1, array2, array3);

The output is:

array1: 0x10010cae0
array2: 0x10010cae0
array3: 0x10010cae0

This makes sense, because NSArray is immutable, and all empty arrays are identical. It looks like NSArray keeps an empty array handy for this purpose since the retain count for the array pointed to by array1, array2, and array3 is 4.

I don't disagree with @fluchtpunkt's answer, but I think it's safe to say that we know exactly why this happens. I suppose you could say that nobody knows exactly why Apple chose to implement it this way, but it does seem like a good idea.

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