为什么我不应该使用getter来释放objective-c中的属性?

JoJ*_*oJo 17 objective-c ios

有人告诉我一个老乡的StackOverflow用户是释放特性时,我不应该使用的getter方法:

@property(nonatmic, retain) Type* variable;
@synthesize variable;

// wrong
[self.variable release]; 

// right
[variable release]; 
Run Code Online (Sandbox Code Playgroud)

他没有详细解释原因.它们看起来和我一样.我的iOS书说,物业上的吸气器将如下所示:

- (id)variable {
    return variable;
}
Run Code Online (Sandbox Code Playgroud)

所以这不是意味着[self variable],self.variable并且variable都是一样的吗?

jrt*_*ton 13

对于没有自定义访问者的保留属性,可以通过以下方式释放对象:

self.variable = nil;
Run Code Online (Sandbox Code Playgroud)

这样可以将ivar(如果只声明了属性,可能不会被称为'变量')设置为nil并释放前一个值.

正如其他人所指出的那样,要么直接释放ivar(如果可用),要么使用上面的方法就可以了 - 你不能做的是对getter返回的变量进行释放.


Mec*_*han 9

您可以选择编写自定义getter行为,这可能会导致完全不同的行为.所以,你不能总是假设它[variable release]具有相同的结果[self.variable release].

同样,您可以编写自定义属性而无需专用的ivar支持它们......如果您开始从getter返回的引用中释放对象,它可能会变得非常混乱!

可能还有其他原因我不知道......

  • 也许getter可以返回一个自动释放的副本?这将是一个可怕的想法,但它仍然是有效的.然后,在这种情况下,释放getter返回的值会通过过度释放对象来使程序崩溃. (3认同)
  • 返回自动释放的对象有原因.你可以有一个属性fullName实现,如`return [[[NSString alloc] initWithFormat:@"%s%s",self.firstName,self.lastName] autorelease];`.如果你以前有一个名字的ivar并且留下了`[self.lastName release]`,你可能会创建一个难以找到的错误.如果你删除了ivar` [lastName release]`会产生编译错误提醒你. (2认同)

omz*_*omz 4

典型的 getter 看起来更像这样:

- (id)variable {
   return [[variable retain] autorelease];
}
Run Code Online (Sandbox Code Playgroud)

因此,如果您使用了[self.variable release]一个额外的对象retain,并且autorelease当您只想释放该对象时并不真正需要该对象,并且这会导致该对象的释放时间晚于必要的时间(当自动释放池耗尽时)。

通常,您可以使用self.variable = nil它的好处,它还可以将变量设置为nil(避免由于悬空指针而导致崩溃),或者如果您的设置器具有自定义逻辑,那么[variable release]它是最快的并且可能更适合方法。dealloc