使用 Cocoa 和 Objective-C 理解引用计数 [英] Understanding reference counting with Cocoa and Objective-C

查看:33
本文介绍了使用 Cocoa 和 Objective-C 理解引用计数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚刚开始研究 Objective-C 和 Cocoa,以尝试使用 iPhone SDK.我对 C 的 mallocfree 概念相当满意,但是 Cocoa 的引用计数方案让我相当困惑.有人告诉我,一旦你理解它,它就会非常优雅,但我还没有克服困难.

I'm just beginning to have a look at Objective-C and Cocoa with a view to playing with the iPhone SDK. I'm reasonably comfortable with C's malloc and free concept, but Cocoa's references counting scheme has me rather confused. I'm told it's very elegant once you understand it, but I'm just not over the hump yet.

releaseretainautorelease 是如何工作的,它们的使用约定是什么?

How do release, retain and autorelease work and what are the conventions about their use?

(或者失败了,你读了什么帮助你得到它的?)

(Or failing that, what did you read which helped you get it?)

推荐答案

让我们从 retainrelease 开始;autorelease 实际上只是您理解基本概念后的一个特例.

Let's start with retain and release; autorelease is really just a special case once you understand the basic concepts.

在 Cocoa 中,每个对象都会跟踪它被引用的次数(具体来说,NSObject 基类实现了这一点).通过在一个对象上调用 retain,你告诉它你想将它的引用计数加一.通过调用 release,你告诉对象你正在释放它,并且它的引用计数减少.如果在调用 release 之后,引用计数现在为零,那么系统会释放该对象的内存.

In Cocoa, each object keeps track of how many times it is being referenced (specifically, the NSObject base class implements this). By calling retain on an object, you are telling it that you want to up its reference count by one. By calling release, you tell the object you are letting go of it, and its reference count is decremented. If, after calling release, the reference count is now zero, then that object's memory is freed by the system.

它与 mallocfree 不同的基本方式是任何给定的对象都不需要担心系统的其他部分崩溃,因为你已经释放了内存他们正在使用.假设每个人都按照规则进行保留/释放,当一段代码保留然后释放对象时,任何其他引用该对象的代码都不会受到影响.

The basic way this differs from malloc and free is that any given object doesn't need to worry about other parts of the system crashing because you've freed memory they were using. Assuming everyone is playing along and retaining/releasing according to the rules, when one piece of code retains and then releases the object, any other piece of code also referencing the object will be unaffected.

有时令人困惑的是知道在什么情况下应该调用 retainrelease.我的一般经验法则是,如果我想保留某个对象一段时间(例如,如果它是类中的成员变量),那么我需要确保该对象的引用计数知道我.如上所述,对象的引用计数通过调用retain 递增.按照惯例,当使用init"方法创建对象时,它也会增加(设置为 1,真的).在这两种情况中的任何一种情况下,我都有责任在处理完对象后在对象上调用 release.如果我不这样做,就会出现内存泄漏.

What can sometimes be confusing is knowing the circumstances under which you should call retain and release. My general rule of thumb is that if I want to hang on to an object for some length of time (if it's a member variable in a class, for instance), then I need to make sure the object's reference count knows about me. As described above, an object's reference count is incremented by calling retain. By convention, it is also incremented (set to 1, really) when the object is created with an "init" method. In either of these cases, it is my responsibility to call release on the object when I'm done with it. If I don't, there will be a memory leak.

对象创建示例:

NSString* s = [[NSString alloc] init];  // Ref count is 1
[s retain];                             // Ref count is 2 - silly
                                        //   to do this after init
[s release];                            // Ref count is back to 1
[s release];                            // Ref count is 0, object is freed

现在是 autorelease.Autorelease 被用作一种方便(有时是必要的)方式来告诉系统在一段时间后释放这个对象.从管道的角度来看,当 autorelease 被调用时,当前线程的 NSAutoreleasePool 会收到该调用的警报.NSAutoreleasePool 现在知道一旦有机会(在事件循环的当前迭代之后),它可以调用对象上的 release.从我们程序员的角度来看,它负责为我们调用 release,所以我们不必(事实上,我们不应该).

Now for autorelease. Autorelease is used as a convenient (and sometimes necessary) way to tell the system to free this object up after a little while. From a plumbing perspective, when autorelease is called, the current thread's NSAutoreleasePool is alerted of the call. The NSAutoreleasePool now knows that once it gets an opportunity (after the current iteration of the event loop), it can call release on the object. From our perspective as programmers, it takes care of calling release for us, so we don't have to (and in fact, we shouldn't).

需要注意的是(同样,按照惯例)所有对象创建方法都返回一个自动释放的对象.例如,在下面的例子中,变量s"的引用计数为1,但在事件循环完成后,它会被销毁.

What's important to note is that (again, by convention) all object creation class methods return an autoreleased object. For example, in the following example, the variable "s" has a reference count of 1, but after the event loop completes, it will be destroyed.

NSString* s = [NSString stringWithString:@"Hello World"];

如果您想保留该字符串,则需要显式调用 retain,然后在完成后显式 release 调用它.

If you want to hang onto that string, you'd need to call retain explicitly, and then explicitly release it when you're done.

考虑以下(非常人为的)代码,您会看到需要 autorelease 的情况:

Consider the following (very contrived) bit of code, and you'll see a situation where autorelease is required:

- (NSString*)createHelloWorldString
{
    NSString* s = [[NSString alloc] initWithString:@"Hello World"];

    // Now what?  We want to return s, but we've upped its reference count.
    // The caller shouldn't be responsible for releasing it, since we're the
    // ones that created it.  If we call release, however, the reference 
    // count will hit zero and bad memory will be returned to the caller.  
    // The answer is to call autorelease before returning the string.  By 
    // explicitly calling autorelease, we pass the responsibility for
    // releasing the string on to the thread's NSAutoreleasePool, which will
    // happen at some later time.  The consequence is that the returned string 
    // will still be valid for the caller of this function.
    return [s autorelease];
}

我意识到所有这些都有些令人困惑 - 但是在某些时候,它会点击.以下是一些帮助您前进的参考资料:

I realize all of this is a bit confusing - at some point, though, it will click. Here are a few references to get you going:

  • Apple 对内存管理的介绍.
  • Mac OS X 的 Cocoa 编程(第 4 版), by Aaron Hillegas - 一本写得很好的书,里面有很多很好的例子.它读起来就像一个教程.
  • 如果您真的很喜欢潜水,可以前往Big Nerd Ranch.这是一个由 Aaron Hillegas 经营的培训机构,他是上述书籍的作者.几年前,我在那里参加了可可入门课程,这是一种很好的学习方式.
  • Apple's introduction to memory management.
  • Cocoa Programming for Mac OS X (4th Edition), by Aaron Hillegas - a very well written book with lots of great examples. It reads like a tutorial.
  • If you're truly diving in, you could head to Big Nerd Ranch. This is a training facility run by Aaron Hillegas - the author of the book mentioned above. I attended the Intro to Cocoa course there several years ago, and it was a great way to learn.

这篇关于使用 Cocoa 和 Objective-C 理解引用计数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆