NSMutabledata。为什么保留计数 1 比我预期的要高?
我每天尝试使用牙线,进行锻炼,并确保保持保留和释放之间的平衡。
这就是让我困惑的地方。我有一个 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
不使用保留计数作为调试辅助是实际的。事实上,经验丰富的 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.
来自 内存管理编程指南:
我从未遇到过查询对象的保留计数很有用的情况。如果您遵循正确的内存管理规则,那就没问题。
至于您的实际问题,自动发布不会立即发生。每当当前的自动释放池碰巧被弹出时,它们就会发生。由于您没有显式管理任何自动释放池,因此您无法控制自动释放何时发生。但是,由于您似乎遵循正确的内存管理规则,因此您无需担心。
From the Memory Management Programming Guide:
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.
也许因为您分配的对象计数为 +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.