如何释放定义为属性的IBOutlet?

时间:2012-02-14 17:18:59

标签: iphone ios memory-management dealloc

对不起这个问题,但是我搜索了一下,但我找不到那个案例的答案。

我正在研究iOS的内存管理,我理解或者我认为是视图生命周期。但是现在我对IBOutlet有一个问题(在我的xib文件中链接到UIImageView)。 我有一个这样的课:

@interface MyClass : UIViewController 

@property (nonatomic, retain) IBOutlet UIImageView *myImage;

问题是:如何发布myImage?这可以吗?

- (void)dealloc {
    self.myImage = nil;
    [super dealloc];
}

- (void)viewDidUnload {
    [super viewDidUnload];
    self.myImage = nil;
}

有人可以解释为什么我不能在myView上调用release方法(如果你有一些喜欢它也很好!)?

提前致谢!

7 个答案:

答案 0 :(得分:3)

IBOutlet无需处理内存管理。

但是因为它是保留属性,所以你需要在dealloc中释放它。

所以你的代码是正确的。

答案 1 :(得分:1)

你正在做的是正确的,你通常会对属性进行呼叫释放,因为设置为nil已经这样做了,但是如果你有一个支持ivar到你的财产,你可以调用释放...

答案 2 :(得分:1)

该属性后面有一个属性和一个实例变量。它们都被称为myImage,我推测(或者你不会问这个问题)。您可以通过两种方式释放实例 - 无论是发布还是仅使用ivar,或只是属性。

编译器生成的保留属性的setter(如下所示)的工作方式如下:释放当前保持的对象引用(如果有),将新值分配给基础ivar,保留它(如果不是nil)。因此,当您为属性指定nil时,它具有释放当前值并将其替换为nil的效果。

为此,请使用

self.myImage = nil; //invoke property setter behind the scenes

要释放ivar,请使用

[myImage release];
myImage = nil;

这在功能上等同于上面的代码。边缘速度更快。你应该清楚的是属性和支持ivars之间的区别。出于这个原因,有些人为他们指定了不同的名称,并合成如下:

@synthesize MyImage = _MyImage;

答案 3 :(得分:1)

一般情况下,您不会在属性上调用release,您可以在相应的ivar上调用它。这是我处理IBOutlet属性的标准方法:

@interface MyClass

@property (nonatomic, retain) IBOutlet UIImageView *myImageView;
@property (nonatomic, retain) IBOutlet UILabel *myLabel;

@end


@implementation MyClass

@synthesize myImageView = _myImageView;
@synthesize myLabel = _myLabel;


- (void)dealloc {

    [_myImageView release];
    [_myLabel release];

    [super dealloc];
}

@end

答案 4 :(得分:1)

来自Apple's documentation

  

传统模式在ARC之前,管理nib对象的规则是   与上述不同。如何管理对象   取决于平台和使用的内存模型。任何   你开发的平台,你应该使用的定义出口   Objective-C声明的属性功能。

     

声明的一般形式应为:

@property (attributes) IBOutlet UserInterfaceElementClass *anOutlet;
  

因为出口的行为取决于平台,实际的声明不同:

     

对于iOS,您应该使用:

@property (nonatomic, retain) IBOutlet UserInterfaceElementClass *anOutlet;
  

对于OS X,您应该使用:

@property (assign) IBOutlet UserInterfaceElementClass *anOutlet;
  

然后你应该合成相应的访问器方法,   或根据声明实施它们,并(在iOS中)发布   dealloc中的相应变量。

     

如果使用现代运行时和合成,此模式也可以使用   实例变量,所以它保持一致   的情况。

答案 5 :(得分:0)

首先:如果您不支持4.0之前的iOS版本,请考虑切换到ARC。

其次,编写dealloc方法的最佳做法是不要调用setter。相反,明确地释放并且没有你的网点:

[myImage release], myImage = nil;

最后,在将viewDidUnload等去初始化方法链接在一起时,请务必在完成自己的工作后调用super的实现。

我们在viewDidUnload中排除出口的原因是因为有时在系统处于内存压力时会卸载视图。由于可以轻松地重新创建这些插座,因此实施viewDidUnload是一种帮助提高性能的方法,并且在极端情况下,可以防止您的应用被强行终止。

我们在dealloc中发布属性的原因是为了防止内存泄漏。因此,尽管这两种方法看起来非常相似,但它们的用途却有所不同。

答案 6 :(得分:0)

我真的不明白你的意思是“为什么我不能在myView上调用发布方法”

您的代码对我来说似乎是正确的,但按照惯例,我通常更喜欢直接释放iVar以获取保留属性 我通常会像这样综合我的财产:

@synthesize myImage = _myImage;

然后我在dealloc方法中释放iVar

- (void)dealloc {
     [_myImage release];
     [super dealloc];
}

Controller中的其他任何地方我只是选择getter和setter(点约定)

您的viewDidUnload是正确的。

顺便说一句,如果您使用ARC,只需将IBOutlet声明为弱指针即可。它将在低内存情况下自动释放,并在视图重新加载后立即重新加载。

希望这会有所帮助;)