分配时为什么需要临时变量?

时间:2011-08-08 18:00:56

标签: objective-c ios

@interface MyViewController : UIViewController {
    UITextField *textField;
}
@property (nonatomic, retain) UITextField *textField;

UITextField *aTextField = [[UITextField alloc] init];   
self.textField = aTextField;
[aTextField release];   

我不知道为什么aTextField是必要的。我不能这样写吗?

@property (nonatomic, assign) UITextField *textField;

self.textField = [[UITextField alloc] init];    

2 个答案:

答案 0 :(得分:5)

澄清:将保留和释放视为增量;对于隐含保留的每个语句,您必须具有平衡发布。保留是“保持此对象存活直到平衡释放”的声明。

几乎;你需要(假设@property(retain) UITextField *textField;):

 textField = [[UITextField alloc] init]; // +1 retain

或者:

 self.textField = [[[UITextField alloc] init] autorelease]; // +1, +1, -1 (delayed)

唯一的区别是上面是直接赋值,并且不使用setter来保留对象。

如果你这样做:

 self.textField = [[UITextField alloc] init]; // +1 +1

你泄漏了这个物体。

而且,是的,在所有正确的情况下,你需要:

self.textField = nil;

或者:

[textField release];

dealloc中。


哦 - 对不起 - 我在第二次assign声明中错过了@property

简而言之,不要这样做。这是一个弱参考,很容易变得悬空。它有它的用途,遗憾的是,它们比它们应该更常见(对象图中的银行指针,最常见的是,代理人也使用它们)。我上面写的内容仍然存在;考虑保留为delta,并且在assign的情况下,没有+1,没有什么可以平衡。

但是,在这种情况下,assign也很可能是不正确的;你想要retain。您可能使用assign并在外部管理保留/释放,但这既不典型又充满脆弱性。属性retain专门用于表达所有权!

答案 1 :(得分:0)

@property (nonatomic, assign) UITextField *textField;

self.textField = [[UITextField alloc] init];

来自对@bbum的评论回答:

  

我没有保留。我帮助了财产。保留计数是1之后   分配。我只需要在dealloc中释放一次。

不要这样做!

好吧,如果之间没有任何事情(属性为assign!),那就不会泄漏,但这违背了对象所有权的基础知识。

标记为assign的属性用于您不拥有的对象,例如委托。因此,根据内存管理规则您不得放弃您不拥有的对象的所有权。

通过这样做,您将遇到很多麻烦,因为您依赖于实现细节,事实上您知道您创建了对象并且需要释放它。你不想让自己处于那个位置。如果你以后设置另一个对象怎么办?你会泄漏前者并可能过度释放后者,导致潜在的崩溃。