可以在Objective C中的属性上调用release吗?

时间:2011-09-01 10:30:43

标签: objective-c ios properties

我最近一直在教自己Objective C,并注意到以下模式在教程和示例代码中使用了很多(包括来自Apple网站的样本)。

UIView *myUiView = [[UIView alloc] init];
self.uiView = myUiView;
[myUiView release];

我只是想知道,创建一个新变量似乎有点浪费,只是为了设置一个属性。我也看到过使用以下模式,但据我所知,在iOS设备上使用autorelease被认为是不好的形式,因为自动释放池占用了相当多的开销,这在移动设备上可能不太好

self.uiView = [[[UIView alloc] init] autorelease];

我最近一直在使用以下模式来设置属性,然后在属性上调用release(以减少属性本身的引用计数器)。

self.uiView = [[UIView alloc] init];
[self.uiView release];

我已经设法在一些没有不良影响的ViewControllers上使用它,但这是有效的代码,还是我错过了一些让它成为坏主意的东西?

5 个答案:

答案 0 :(得分:1)

如果属性getter的实现只是返回对底层ivar的引用,那么它完全等效,你只需减少已分配对象的保留计数。

另一方面,如果你不能确定吸气剂是做什么的(如果它返回除了ivar以外的东西,例如一些计算结果等),那么它可能是危险的。

答案 1 :(得分:1)

属性getter是一个方法,它不必返回一个ivar,它实际上可以在任何地方获得它的返回值,所以你可以释放它,但它可能已经是一个自动释放的值。如果是这样的话,那你就麻烦了。

IOW,如果属性getter会做类似的事情(不常见,但可能有效):

- (NSString *) helloString
{
    return [[myStringIVar copy] autorelease];
}

你做了:

[self.helloString release];

然后你以两种方式失败了:

  • 您没有发布想要发布的ivar
  • 您发布了自动释放的对象

IMO,最好直接发布ivar:

[myStringIVar release];

答案 2 :(得分:1)

它无效,即使在它工作的情况下它有点“丑陋”,另外两个只是修复属性的保留特性,使得在已经使保留计数为1之后保留计数2。

我倾向于做你在第一个例子或下面描述的内容。

在我的@interface

@property (nonatomic, retain) UIView *uiView;

在我的@implementation

@synthesize uiView = _uiView;

然后我设置了属性。

_uiView = [[UIView alloc] init];

答案 3 :(得分:1)

没有。它无效。

它可能适用于大多数保留属性,但不一定。它可能会破坏复制属性并分配属性。

属性只是一对方法,其中一个设置一个抽象实体,另一个设置它。 一般来说,绝对不能保证getter会为您提供刚刚传递给setter的完全相同的对象。例如,如果将可变字符串传递给NSString复制属性,你绝对不会回到同一个对象。

使用前两种模式中的任何一种。第一个不浪费任何东西。局部变量很可能只存在于寄存器中。第二个的开销只会持续下一个自动释放池耗尽并且只有几个字节(请记住,实际对象在任何情况下都会持续self。)

答案 4 :(得分:0)

根据引用计数器进行思考,使用属性值调用release没有任何问题。但是,有些事情我个人不喜欢:

属性语法实际上只是方法调用的语法糖。那么,你的代码真正的样子是

[self setUiView: [[UIView alloc] init]];
[[self uiView] release];

这里的另一件事可能更多是由于我以奇怪的方式思考,但我喜欢将引用计数视为实际与引用有关。保存指向我的对象的指针的局部变量就是这样的引用。让它出现在代码中提醒我,我有一些事情要做,以便妥善清理(或者,如果没有,至少写一个简短的评论,为什么我不需要清理)。

直接通过该物业迫使我考虑引用计数,而我不喜欢。