NSMutabledata。为什么保留计数 1 比我预期的要高?

发布于 2024-08-07 21:23:18 字数 1303 浏览 9 评论 0原文

我每天尝试使用牙线,进行锻炼,并确保保持保留和释放之间的平衡。

这就是让我困惑的地方。我有一个 ivar:

NSMutabledata *_alignmentData 

以及与之关联的综合属性:

// .h file
@property (nonatomic, retain) NSMutableData *alignmentData;

// .m file
@synthesize alignmentData=_alignmentData;

我开始从服务器异步提取数据:

self.connection = 
[[[NSURLConnection alloc] initWithRequest:theRequest delegate:self] autorelease];

在分配一个数据缓冲区之后立即在异步回调中使用:

// This prints 0. Cool.
NSLog(@"BEFORE [_alignmentData retainCount] = %d", [_alignmentData retainCount]);

// Create a place to receive the data that will arrive asynchronously:
self.alignmentData = [NSMutableData data];

// This prints 2. Shouldn't this be 1 ?!?
NSLog(@" AFTER [_alignmentData retainCount] = %d", [_alignmentData retainCount]);

使之后触发的第一个异步回调中的问题变得复杂上面的 self.alignmentData 分配,我再次检查保留计数:

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {

    // This prints 1. 
    NSLog(@"[_alignmentData retainCount] = %d", [_alignmentData retainCount]);
    [self.alignmentData setLength:0];

}

所以,看起来保留计数从 0 上升到 2,然后下降到 1。有人可以向我解释这是怎么可能的吗?

注意:我被告知不要使用保留计数作为调试辅助工具,但这在非垃圾收集语言(例如 Objective-C)中根本不实用。

I am trying to floss daily, get my exercise, and make sure I maintain a balance between my retains and releases.

Here is what has me puzzled. I have a ivar:

NSMutabledata *_alignmentData 

and a synthesized property associated with it:

// .h file
@property (nonatomic, retain) NSMutableData *alignmentData;

// .m file
@synthesize alignmentData=_alignmentData;

I start to pull data from a server asynchronously:

self.connection = 
[[[NSURLConnection alloc] initWithRequest:theRequest delegate:self] autorelease];

And immediately after allocate a data buffer to be used subsequently in the asynchronous callbacks:

// This prints 0. Cool.
NSLog(@"BEFORE [_alignmentData retainCount] = %d", [_alignmentData retainCount]);

// Create a place to receive the data that will arrive asynchronously:
self.alignmentData = [NSMutableData data];

// This prints 2. Shouldn't this be 1 ?!?
NSLog(@" AFTER [_alignmentData retainCount] = %d", [_alignmentData retainCount]);

To complicate matters in the first asynchronous callback that fires after the above allocation of self.alignmentData, I inspect the retain count again:

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {

    // This prints 1. 
    NSLog(@"[_alignmentData retainCount] = %d", [_alignmentData retainCount]);
    [self.alignmentData setLength:0];

}

So, it appears that the retain count rises to 2 from 0 then drops to 1. Can someone explain to me how this is possible?

Note: I've been told not to use retain counts as a debugging aid but that is simply not practical in a non-garbage collected language such as Objective-C.

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

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

发布评论

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

评论(3

一杆小烟枪 2024-08-14 21:23:18

不使用保留计数作为调试辅助是实际的。事实上,经验丰富的 Objective-C 程序员会告诉你不要关注保留计数。一般来说,担心这些问题的人都是刚接触 Objective-C 的程序员,他们最终会像您一样感到困惑。

您不必太担心保留计数。事实上,某些东西的保留量比您预期的多,并不一定与您的代码有任何关系,也不一定表明存在错误,确定这种情况的唯一方法是使用适当的调试工具,就像您建议的那样首先做。

在这种特殊情况下,2 是该对象在该时间点的正确保留计数,因为它是使用保留计数 1 创建的,然后由您的 setter 方法保留。

It IS practical not to use retain counts as a debugging aid. In fact, it's experienced Objective-C coders who will tell you not to pay attention to retain counts. The people who worry about them in general are coders new to Objective-C, and they wind up being confused like you are.

You should not worry much about retain counts. The fact that something has more retains than you expect does not necessarily have anything to do with your code and does not necessarily indicate a bug, and the only way to determine which is the case is to use a proper debugging tool like you were advised to do in the first place.

In this particular case, 2 is the correct retain count for that object at that point in time because it was created with a retain count of 1, then retained by your setter method.

葬﹪忆之殇 2024-08-14 21:23:18

来自 内存管理编程指南

保留计数

通常没有理由明确询问对象的保留计数是多少(请参阅retainCount)。结果通常会产生误导,因为您可能不知道哪些框架对象保留了您感兴趣的对象。在调试内存管理问题时,您应该只关心确保您的代码遵守所有权规则。

我从未遇到过查询对象的保留计数很有用的情况。如果您遵循正确的内存管理规则,那就没问题。

至于您的实际问题,自动发布不会立即发生。每当当前的自动释放池碰巧被弹出时,它们就会发生。由于您没有显式管理任何自动释放池,因此您无法控制自动释放何时发生。但是,由于您似乎遵循正确的内存管理规则,因此您无需担心。

From the Memory Management Programming Guide:

Retain Count

Typically there should be no reason to explicitly ask an object what its retain count is (see retainCount). The result is often misleading, as you may be unaware of what framework objects have retained an object in which you are interested. In debugging memory management issues, you should be concerned only with ensuring that your code adheres to the ownership rules.

I've never come across a situation where it's been useful to query an object's retainCount. If you follow proper memory management rules, you'll be fine.

As for your actual question, autoreleases don't happen immediately. They happen whenever the current autorelease pool happens to be popped. Since you're not explicitly managing any autorelease pools, then you have no control over when that autorelease happens. However, since you seem to be following correct memory management rules, you have nothing to worry about.

盗梦空间 2024-08-14 21:23:18

也许因为您分配的对象计数为 +1 和 autorelase,然后它被设置为一个属性,该属性调用它的保留,所以 +2,并且原始对象被自动释放,所以它下降到 +1。

Maybe because you're allocating the object with a count of +1 and autorelase, then it get set to a property, which calls a retain on it, so +2, and the original object is autoreleased, so it drops to +1.

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