跳至内容

Cocoa 编程/内存管理

来自维基教科书,开放的书籍,为开放的世界

有人,请修复此页面

动态分配

[编辑 | 编辑源代码]

在 Objective-C(与 C++ 不同)中,所有对象都是动态创建的。这意味着它们将一直存在,直到它们被明确销毁。

要创建一个对象,请向其类发送一个分配消息[aClass alloc];。请注意,这将返回一个新类的实例,但不会初始化其数据。通常您希望立即向新对象发送一个初始化消息来弥补这一点。分配和初始化通常在一行代码中结合在一起

aClass *newobj = [[aClass alloc] init];

有一个名为的类方法,它分配并提供对象的基本初始化,但已弃用,取而代之的是分配初始化.

引用计数

[编辑 | 编辑源代码]

在 C++ 中,每个动态创建的对象都需要显式删除(使用删除运算符)。在 Java 中,每个动态创建的对象(即每个对象)都会在垃圾收集器检测到对象不再被引用时自动删除。在 Objective-C 中,没有使用这两种方法。

Objective-C 对象维护一个引用计数。当创建对象时,其引用计数初始化为 1。当引用计数达到零时,对象将自行销毁。

要告诉对象您不再使用它,请向它发送一个释放消息:"[anObject release];". 这会将对象的引用计数减 1。如果您是对象的最后一个用户,该对象将自行销毁。

在发送释放到对象之后,不安全再使用该对象,因为该对象可能已自行销毁。

当您要保留一个对象,即阻止它消失时,请向它发送一个保留消息:"[anObject retain];". 请注意,您不应向使用分配消息创建的对象发送保留消息,因为分配始终意味着保留。因此,保留仅在您需要使用在其他地方创建的对象(并且将在该部分程序不再需要它时从那里发送释放消息)时才需要。

每个保留都需要与一个且仅一个释放匹配。请注意,, 分配, 复制可变复制方法也隐式地保留返回的对象,因此这些方法也需要与释放.

自动释放池

[编辑 | 编辑源代码]

有时无法立即释放对象:例如,函数创建了一个对象并希望将其返回给调用者。现在,被调用者应释放它创建的不再使用的对象。但是,调用者需要访问返回的对象。如果被调用者释放创建的对象,调用者将永远看不到返回值。一个解决方案是在被调用者中跳过释放对象,并要求调用者释放它。这很容易出错,并且违反了“每个保留与一个释放匹配”的原则。

在 Objective-C/OpenStep 运行时,可以向对象发送自动释放消息。这将导致对象被添加到当前的自动释放池中。自动释放池中的对象将在将来的某个时间点(当前自动释放池被销毁时)被释放。在之前,它们是安全的。

如果调用者想保留返回的对象,它必须保留它。否则,该对象将被自动释放。示例

   /* In class Environment, responsible of telling details of current environment: */
   - (id) nameOfLang        /* the callee */
   {
       id name = [[NSString alloc] initWithCString: "Objective-C"];
       [name autorelease];
       return name;
   }

   /* In another class where environment info is needed */
   - (void) getName        /* the caller */
   {
       myLangName = [environment nameOfLang];   /* myLangName is an instance variable */
       [myLangName retain];              /* Will be released when this object no longer needs it */
   }
华夏公益教科书