对不起这个问题,但是我搜索了一下,但我找不到那个案例的答案。
我正在研究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方法(如果你有一些喜欢它也很好!)?
提前致谢!
答案 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)
传统模式在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
声明为弱指针即可。它将在低内存情况下自动释放,并在视图重新加载后立即重新加载。
希望这会有所帮助;)