简体   繁体   English

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

[英]NSMutabledata. Why is the retain count 1 higher that I would have expected?

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: 我有一个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: 为了使在上述self.alignmentData分配之后触发的第一个异步回调中的问题复杂化,我再次检查了保留计数:

- (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? 因此,似乎保留计数从0增加到2,然后下降到1。有人可以向我解释这是怎么可能的吗?

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. 注意:有人告诉我不要将保留计数用作调试辅助工具,但这在非垃圾收集语言(例如Objective-C)中根本不可行。

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 ). 通常,没有理由明确询问对象的保留计数是多少(请参见keepCount )。 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. 我从来没有遇到过查询对象的keepCount有用的情况。 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. 但是,由于您似乎遵循了正确的内存管理规则,因此您无需担心。

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. 实际上,经验丰富的Objective-C编码人员会告诉您不要注意保留计数。 The people who worry about them in general are coders new to Objective-C, and they wind up being confused like you are. 通常,担心它们的人是Objective-C的新手,就像您一样,他们一头雾水。

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. 在此特定情况下,2是该对象在该时间点的正确保留计数,因为它是用保留计数1创建的,然后由您的setter方法保留。

也许是因为您要分配的对象的计数为+1,并且会自动释放,然后将其设置为一个属性,该属性将对其调用一个keep,即+2,并且原始对象会自动释放,因此它降至+1。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM