0

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

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

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

4

3 回答 3

5

内存管理编程指南

保留计数

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

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

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

于 2009-10-17T20:19:07.423 回答
5

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

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

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

于 2009-10-17T20:27:02.870 回答
3

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

于 2009-10-17T20:18:23.627 回答