NSM 可变数据。为啥保留计数 1 比我预期的要高?
Posted
技术标签:
【中文标题】NSM 可变数据。为啥保留计数 1 比我预期的要高?【英文标题】:NSMutabledata. Why is the retain count 1 higher that I would have expected?NSM 可变数据。为什么保留计数 1 比我预期的要高? 【发布时间】:2009-10-17 20:13:20 【问题描述】:我正在尝试每天使用牙线,锻炼身体,并确保在保留和释放之间保持平衡。
这让我感到困惑。我有一个 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 之类的非垃圾收集语言中根本不实用。
【问题讨论】:
【参考方案1】:不使用保留计数作为调试辅助是切实可行的。事实上,经验丰富的 Objective-C 编码人员会告诉你不要注意保留计数。担心他们的人通常是 Objective-C 的新手,他们最终会像你一样感到困惑。
您不必担心保留计数。某些东西比您预期的保留更多的事实不一定与您的代码有任何关系,也不一定表明存在错误,确定是哪种情况的唯一方法是使用适当的调试工具,就像您被建议的那样首先做。
在这种特殊情况下,2 是该对象在该时间点的正确保留计数,因为它是使用保留计数 1 创建的,然后由您的 setter 方法保留。
【讨论】:
是的,是的,查克。我知道我在平衡我的保留/释放方面很清楚。我不漏。 Clang说我可以走了。我现在正式发誓不再为保留计数而烦恼。承诺。感谢您 - 实际上相当严厉 - 警告。 对不起,如果听起来过于严厉。那真的不是我的本意。我一直在寻求清晰而不是看我的语气,因为我认识一些人花了很多时间担心保留计数,这真的只是浪费时间,所以我想帮助人们尽早而不是迟到.【参考方案2】:来自Memory Management Programming Guide:
保留计数
通常没有理由明确询问对象的保留计数是多少(请参阅retainCount)。结果通常具有误导性,因为您可能不知道哪些框架对象保留了您感兴趣的对象。在调试内存管理问题时,您应该只关心确保您的代码遵守所有权规则。
我从未遇到过查询对象的retainCount 很有用的情况。如果你遵循正确的内存管理规则,你会没事的。
至于您的实际问题,自动发布不会立即发生。每当当前的自动释放池恰好被弹出时,它们就会发生。由于您没有明确管理任何自动释放池,因此您无法控制自动释放何时发生。但是,由于您似乎遵循了正确的内存管理规则,因此您无需担心。
【讨论】:
【参考方案3】:可能是因为您正在分配计数为 +1 和自动释放的对象,然后它被设置为一个属性,该属性调用它的保留,所以 +2,原始对象是自动释放的,所以它下降到+1。
【讨论】:
这是正确答案,[NSData data] 返回一个自动释放的对象。 小精灵,啊哈!我开始怀疑这一点。 Autorelease 是 retainCount 暂时上升的隐藏原因。非常感谢。以上是关于NSM 可变数据。为啥保留计数 1 比我预期的要高?的主要内容,如果未能解决你的问题,请参考以下文章