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

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

问题描述

我刚刚开始看看Objective-C和Cocoa,以便使用iPhone SDK。我对C的 malloc 自由概念感到相当舒服,但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.

如何发布

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

推荐答案

让我们从 retain release 开始; autorelease 实际上只是一个特殊的情况下,一旦你理解了基本概念。

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

在Cocoa中,每个对象都跟踪它被引用的次数(具体来说, NSObject 实现此)。通过在对象上调用 retain ,可以告诉它要将其引用计数加1。通过调用 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.

malloc 自由不同的基本方式是任何给定的对象不需要担心其他部分的系统崩溃,因为你释放了他们正在使用的内存。假设每个人都按照规则玩,并保留/释放,当一段代码保留然后释放对象时,引用对象的任何其他代码段也不受影响。

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.

有时可能令人困惑的是知道应该调用 retain release 的情况。我的一般经验法则是,如果我想挂在对象上一段时间(如果它是一个类中的成员变量,例如),那么我需要确保对象的引用计数知道我。如上所述,通过调用 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 时,当前线程的 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"];

如果你想挂在那个字符串上,你需要调用保持,然后在完成后显式地释放

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版),由Aaron Hillegas - 一本非常好的书,有很多很好的例子。

  • 如果你真的潜水,你可以前往大内尔德牧场。这是一个训练设施由亚伦Hillegas运行 - 上述书的作者。我参加了几年前的Cocoa课程介绍,这是一个很好的学习方式。

  • 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天全站免登陆