ios 如何在 ARC 模式下验证引用计数?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8863269/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 16:18:29  来源:igfitidea点击:

How do I verify reference count in ARC mode?

iphoneiosautomatic-ref-counting

提问by tomsoft

I used to verify that some of my variables had the expected retain count using [myVar retainCount] under the debugger, especially for var that did not have a custom dealloc.

我曾经在调试器下使用 [myVar retainCount] 来验证我的一些变量是否具有预期的保留计数,特别是对于没有自定义 dealloc 的 var。

How do you do this in ARC mode? How do you ensure that there are no memory leaks?

你如何在ARC模式下做到这一点?你如何确保没有内存泄漏?

Note: I understand that ARC should handle this for me, but life is far from being perfect, and in real life you have objects that are sometimes allocated by third party libraries (using retain?) and never deallocated.

注意:我知道 ARC 应该为我处理这个问题,但生活远非完美,在现实生活中,您的对象有时由第三方库分配(使用保留?)并且从未被释放。

Image that I do this:

我这样做的图像:

MyObj *myObj=[[MyObj alloc] init];

then I call

然后我打电话

[somethingElse doSomethingWithMyObj:myObj];

and later, I do

后来,我做

myObj=NULL;

If my program is working fine, my expectation is that myObj is being destroyed, but it appears not to be the case...

如果我的程序运行良好,我的期望是 myObj 被销毁,但情况似乎并非如此......

So how can I track this, especially if somethingElse is not managed by me?

那么我如何跟踪这个,特别是如果 somethingElse 不是由我管理的?

Now, about the tools: it seems extremely hard to run memory tools on my mac (with 5 Meg) without rebooting the mac and starting from scratch. This is really annoying! Instruments keep crashing even before the program has started, so is there an alterante solution?

现在,关于工具:在我的 mac(有 5 Meg)上运行内存工具似乎非常困难,而无需重新启动 mac 并从头开始。这真的很烦人!仪器甚至在程序启动之前就一直崩溃,所以有替代解决方案吗?

回答by rob mayoff

You can use CFGetRetainCountwith Objective-C objects, even under ARC:

CFGetRetainCount即使在 ARC 下,您也可以与 Objective-C 对象一起使用:

NSLog(@"Retain count is %ld", CFGetRetainCount((__bridge CFTypeRef)myObject));

This is notparticularly useful for debugging, though, for reasons amply described elsewhere. If you need to understand where an object is being retained and released, check out this answerfor help using the Allocations instrument.

但是,由于其他地方充分描述的原因,这对于调试并不是特别有用。如果您需要了解保留和释放对象的位置,请查看此答案以获取使用分配工具的帮助。

The only case I've found where examining the retain count is actually useful is in a deallocmethod, when something retains and autoreleases the object being deallocated. This will cause a crash later when the autorelease pool is drained. You can pinpoint the cause of this by checking the retain count before and after each message. In this way I discovered that the observationInfomethod(which is itself usually only useful for debugging) retains and autoreleases self. However, even this sort of problem can usually be solved without examining the retain count, simply by wrapping the entire body of deallocin an @autoreleasepoolblock.

我发现检查保留计数实际上有用的唯一情况是在dealloc方法中,当某些内容保留并自动释放正在释放的对象时。这将导致稍后在自动释放池耗尽时崩溃。您可以通过检查每条消息前后的保留计数来查明造成这种情况的原因。通过这种方式,我发现observationInfo方法(它本身通常只对调试有用) retains 和 autoreleases self。然而,即使是这类问题通常也可以在不检查保留计数的情况下解决,只需将整个主体包装dealloc在一个@autoreleasepool块中即可。

However, the retain count can be used to learn about the implementation of some classes. (Only do this for entertainment or curiosity! Never rely on undocumented implementation details in production code!)

但是,保留计数可用于了解某些类的实现。(这样做只是为了娱乐或好奇!永远不要依赖生产代码中未记录的实现细节!)

For example, try this immediately inside the @autoreleasepoolin main:

例如,立即在@autoreleasepoolin 中尝试此操作main

NSNumber *n0 = [[NSNumber alloc] initWithInt:0];
NSLog(@"0 reference count = %ld", CFGetRetainCount((__bridge CFTypeRef)n0));
// Prints 2 in my test

So NSNumberlikely caches (or at least reuses) some instances. But not others:

因此NSNumber可能会缓存(或至少重用)某些实例。但不是其他人:

n0 = [[NSNumber alloc] initWithInt:200];
NSLog(@"n0 reference count = %ld", CFGetRetainCount((__bridge CFTypeRef) n0));
// Prints 1 - I am the sole owner of this instance.  There could be weak
// or unretained references to it, but no other strong references.

NSNumber *n1 = [[NSNumber alloc] initWithInt:200];
NSLog(@"n1 reference count = %ld", CFGetRetainCount((__bridge CFTypeRef) n1));
// Prints 1 again.  New instance with same value as prior instance.
// You could of course compare pointers to see that they are separate
// instances.

You can even discover that NSNumberreturns a singleton if you allocbut don't initialize:

你甚至可以发现,NSNumber如果你alloc不初始化,它会返回一个单例:

n1 = [NSNumber alloc];
NSLog(@"n1 reference count = %ld", CFGetRetainCount((__bridge CFTypeRef) n1));
// Prints -1.

(Note that you can also learn many details about NSNumberby looking at the Core Foundation source code, which is available at http://opensource.apple.com. But who knows what you might find if you look at the retain count of objects that aren't toll-free-bridged with objects in Core Foundation?)

(请注意,您还可以NSNumber通过查看 Core Foundation 源代码(可在http://opensource.apple.com上获得)来了解更多详细信息。但是如果您查看对象的保留计数,谁知道您会发现什么?不是与 Core Foundation 中的对象免费桥接的吗?)

回答by Colin Wheeler

You don't. ARC handles the memory management for you and does not allow you to call retainCount and even if you could see it, the number it returns is meaningless for you. If you want to you should be doing memory profiling in Instruments with the Leaks and Allocations instruments. That is the best way to look and see how your application is allocating memory and catch any improper use of memory there.

你没有。ARC 为您处理内存管理,并且不允许您调用 retainCount,即使您可以看到它,它返回的数字对您来说也毫无意义。如果您愿意,您应该使用 Leaks 和 Allocations 工具在 Instruments 中进行内存分析。这是查看您的应用程序如何分配内存并在那里发现内存的任何不当使用的最佳方式。

回答by UIAdam

You should never use retainCount for anything, with or without ARC.

无论是否使用 ARC,您都不应该将 retainCount 用于任何事情。

When to use -retainCount?

何时使用 -retainCount?

回答by Henrik Hartz

Use Instruments and locate the object you want to track by searching for the class name or pointer address if you have it while in in "Objects List".

使用 Instruments 并通过搜索类名或指针地址来定位您要跟踪的对象(如果您在“对象列表”中有它的话)。

When you have located it, hit the disclosure arrow on the instance. This brings you to a history view for retains and relases.

找到它后,点击实例上的披露箭头。这将带您进入保留和重新发布的历史视图。

If you expand the right side detail view you will also see the callstack for each retain/release.

如果展开右侧详细信息视图,您还将看到每个保留/释放的调用堆栈。

Instruments showing object history and callstack detail

Instruments showing object history and callstack detail

回答by Aaron Hayman

I believe the only way is to profile your application using the Allocations instrument. You will need to click on the info descriptor (the 'i' next to Allocation in the left pane) and click on "Record Reference Counts". You can then profile your app and do a search for the specific class you're looking to inspect. From there you can find the retain count in the Extended Detail pane for each instance of the class.

我相信唯一的方法是使用 Allocations 工具分析您的应用程序。您需要单击信息描述符(左窗格中分配旁边的“i”),然后单击“记录引用计数”。然后,您可以分析您的应用程序并搜索您要检查的特定类。从那里您可以在扩展详细信息窗格中找到类的每个实例的保留计数。

You can also do this using Leaks as well (since I believe it's a variation of the Allocations instrument).

您也可以使用 Leaks 来做到这一点(因为我相信它是 Allocations 工具的一种变体)。

回答by Jason Yu

Get the object's retainCount?

获取对象的retainCount?

You can just make a breakpoint and input the command below to get the object's retainCount

您可以创建一个断点并输入下面的命令来获取对象的 retainCount

po object.retainCount

回答by Darren

You don't. Apple say you don't need to as ARC will handle it for you.

你没有。Apple 说您不需要,因为 ARC 会为您处理。