如何释放定义为属性的IBOutlet?
对不起这个问题,但我搜索了一下,但我找不到那个案例的答案。
我正在研究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方法(如果你有一些喜欢它也很好!)?
提前致谢!
一般情况下,您不会在属性上调用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
IBOutlet没有什么可以处理内存管理。
但因为它是保留属性,所以你需要在dealloc中释放它。
所以你的代码是正确的。
你正在做的是正确的,你通常会在属性上调用释放,因为设置为nil已经这样做了,但是如果你有一个支持ivar到你的属性你可以调用释放…
该属性后面有一个属性和一个实例变量。 它们都被称为myImage,我推测(或者你不会问这个问题)。 您可以通过两种方式释放实例 – 无论是释放还是无效的ivar,或者只是属性。
编译器生成的保留属性的setter(如下所示)的工作方式如下:释放当前保持的对象引用(如果有),将新值分配给基础ivar,保留它(如果不是nil)。 因此,当您为属性指定nil时,它具有释放当前值并将其替换为nil的效果。
为此,请使用
self.myImage = nil; //invoke property setter behind the scenes
要释放伊娃,请使用
[myImage release]; myImage = nil;
这在function上等同于上面的代码。 边缘速度更快。 你应该清楚的是属性和支持ivars之间的区别。 出于这个原因,有些人为它们指定了不同的名称,并合成如下:
@synthesize MyImage = _MyImage;
来自Apple的文档 :
遗留模式在ARC之前,管理nib对象的规则与上述规则不同。 管理对象的方式取决于平台和使用的内存模型。 无论您开发哪种平台,都应使用Objective-C声明的属性function定义出口。
宣言的一般forms应为:
@property (attributes) IBOutlet UserInterfaceElementClass *anOutlet;
因为出口的行为取决于平台,实际的声明不同:
对于iOS,您应该使用:
@property (nonatomic, retain) IBOutlet UserInterfaceElementClass *anOutlet;
对于OS X,您应该使用:
@property (assign) IBOutlet UserInterfaceElementClass *anOutlet;
然后,您应该合成相应的访问器方法,或者根据声明实现它们,并且(在iOS中) 在dealloc中释放相应的变量。
如果您使用现代运行时并合成实例变量,此模式也可以工作,因此它在所有情况下都保持一致。
首先:如果您不支持4.0之前的iOS版本,请考虑切换到ARC。
其次,编写dealloc
方法的最佳实践是不要调用setter。 相反,明确释放你的网点:
[myImage release], myImage = nil;
最后,当将像viewDidUnload
这样的去初始化方法链接在一起时,总是在你自己的工作之后调用super
的实现。
我们在viewDidUnload
中viewDidUnload
出口的原因是因为有时在系统处于内存压力时卸载视图。 由于可以轻松地重新创建这些sockets,因此实现viewDidUnload
是一种帮助提高性能的方法,并且在极端情况下,可以防止您的应用被强制终止。
我们在dealloc
释放属性的原因是为了防止内存泄漏。 因此即使这两种方法看起来非常相似,它们的用途也有所不同。
我真的不明白你的意思是“为什么我不能在myView上调用release方法”
你的代码对我来说似乎是对的,但按照惯例,我通常更喜欢直接发布iVar以获取保留属性我通常会像这样合成我的属性:
@synthesize myImage = _myImage;
然后你我在dealloc方法中释放iVar
- (void)dealloc { [_myImage release]; [super dealloc]; }
控制器中的其他任何地方我只是选择getter和setter(点约定)
你的viewDidUnload是正确的。
顺便说一句,如果您使用ARC,只需将您的IBOutlet
声明为弱指针。 它将在低内存情况下自动释放,并在视图再次加载后重新加载。
希望这会有所帮助;)
- iOS – 在UIViewController中展示一个UIViewController
- 如何实现iPhone的音量快门键?
- 在iOS 7中,尽pipeUITabBarController被隐藏了,为什么UITableView的contentInset有底部值?
- uitableview内的多个倒计时定时器
- UINavigationController方法setToolbarHidden在Xcode 9中的bug:自动布局约束的无限计算导致OOM
- 按升序对NSDictionary进行sorting
- navigationBar和MPMoviePlayerController极其怪异的行为。 在iOS中的错误或我的错误?
- 将模型对象从一个视图控制器传递到另一个导航堆栈中
- iPhone – 在应用程序启动时,应用程序进入后台