1

我有点理解自动保留和释放的内容,但我找不到任何官方数据,我认为我做错了。

  1. 设置使用 @property(retain) 声明的属性将保留和释放旧值,但不会在同一对象内设置属性self.
  2. 方法内的所有对象(包括参数)在创建/传递时保留,在方法返回时释放。
  3. 方法返回的对象不会被释放,而是会被返回到的方法释放,因为它是方法内部的局部变量。

我做错了什么/忘记了什么吗?
当退货被丢弃时会发生什么?喜欢[object someMethodThatReturnsAnObject];。它不会是它返回的方法的本地,所以我不确定它是否会被释放并且 xCode 会发出警告。

4

3 回答 3

3

与其猜测,不如阅读文档。这是确定的。

设置使用 @property(retain) 声明的属性将保留和释放旧值,但不会在没有 self 的同一对象内设置属性。

有点。没有“设置没有自我的属性”。那就是直接设置一个实例变量。

方法内的所有对象(包括参数)在创建/传递时保留,在方法返回时释放。

没有; 请参阅文档。

方法返回的对象不会被释放,而是会被返回到的方法释放,因为它是方法内部的局部变量。

一点也不; 请参阅文档。

于 2011-06-16T20:12:41.833 回答
2

设置使用 @property(retain) 声明的属性将保留和释放旧值,但不会在没有 self 的同一对象内设置属性。

调用为保留属性合成的 setter 方法将释放旧值并保留新值。直接设置 ivar,而不通过您的访问器,只会分配 ivar。它既不会保留也不会释放任何东西。self.foo = bar正是。_ [self setFoo:bar]无论做什么setFoo:都会做(setFoo:如上所述的合成保留版本的作品)。foo = bar正是。_ foo = bar

方法内的所有对象(包括参数)在创建/传递时保留,在方法返回时释放。

这根本不是真的。它们既不保留也不释放。保留和释放不会神奇地发生。它一方面响应对alloc, new, copy,的调用而发生,另一方面。使用点表示法只是可能有内部方法调用的简写。retainreleaseretain

方法返回的对象不会被释放,而是会被返回到的方法释放,因为它是方法内部的局部变量。

这不是真的。方法返回的对象既不会被保留也不会被释放。alloc按照惯例,带有newcopy在其名称中的方法将返回净 +1 保留。任何其他方法都将返回净 0 保留计数(对象上的自动释放与保留一样多)。“当前”保留计数将始终大于 0,否则无法返回对象。(这是对事实的轻微掩饰。如果存在私有保留,则任何一种情况下的保留计数都可能大于 1。但从调用者的角度来看,这是一种有用的思考方式。)

最好的地方是Practical Memory Management,它非常简洁地说明了这一切。内存管理编程指南的其余部分将提供更多示例。

于 2011-06-16T20:16:43.820 回答
1

“自动”这个词有点吓人。这意味着在幕后运行时以某种方式神奇地应用了保留和释放。真的,唯一一次保留的内容是发送包含以下内容之一的消息:New Alloc Retain Copy (NARC)。它被释放的唯一时间是发送释放消息或自动释放消息时。那么你真正需要了解的是,这些方法是在什么情况下发送的?

1. 设置属性
就您而言,您是正确的。为什么?因为属性只是生成 getter 和 setter 方法的语法糖。例如,self.myString = @"Foo";与 绝对相同[self setMyString:@"Foo"]。您需要了解的是,当您声明一个具有保留语义的属性时,您实际上会得到一个如下所示的方法:

- (void)setMyString:(NSString *)newString {
    if ( newString != myString ) {
        [myString release];
        myString = [newString retain];
    }
}

因此,很明显,说self.myString = someOtherString将导致新值被保留。您所说的“不设置属性self.”实际上只是直接的 ivar 分配。由于没有使用点运算符,因此没有调用任何方法,因此您知道没有保留任何内容。

2. 和 3. 与方法范围有关吗?
这些都不是真的。约定说返回我的方法的变量在名称中没有 NARC 的痕迹将被自动释放。方法作者要真正遵守约定。任何东西都不会因为方法调用而自动保留或释放。

于 2011-06-16T20:24:20.420 回答