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

时间:2009-10-17 20:13:21

标签: iphone objective-c release nsdata retain

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

这让我感到困惑。我有一个伊娃:

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)来说根本不实用。

3 个答案:

答案 0 :(得分:5)

来自Memory Management Programming Guide

  

保留计数

     

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

我从未遇到过查询对象的retainCount有用的情况。如果你遵循适当的内存管理规则,你会没事的。

至于你的实际问题,自动释放不会立即发生。只要弹出当前的自动释放池,就会发生这种情况。由于您没有明确管理任何自动释放池,因此您无法控制何时发生自动释放。但是,由于您似乎遵循了正确的内存管理规则,因此您无需担心。

答案 1 :(得分:5)

实际上不使用保留计数作为调试辅助工具。事实上,它是经验丰富的Objective-C编码员,会告诉你不要注意保留计数。一般担心他们的人都是Objective-C的新手,他们最终会像你一样感到困惑。

你不应该担心保留计数。事物有更多的保留而不是你期望的事实并不一定与你的代码有任何关系,并不一定表明存在错误,唯一的方法来确定是哪种情况是使用适当的调试工具,就像你被建议的那样首先要做。

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

答案 2 :(得分:3)

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