How to release IBOutlet defined as property?

99封情书 提交于 2019-12-08 02:45:38

问题


sorry for this question, but I searched it and I didn't find an answer for that case.

I'm studying memory management for iOS and I understood, or I think so, the view lifecycle. But now I have a question on a IBOutlet (tat is linked to a UIImageView in my xib file). I have a class like this:

@interface MyClass : UIViewController 

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

The question is: how can I release myImage? Is this ok?

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

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

Can someone explain why can't I call the release method on myView (if you had some lik it is good too!)?

Thanks in advance!


回答1:


In general, you don't call release on a property, you would call it on the corresponding ivar. This is my standard way to handle IBOutlet properties:

@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



回答2:


IBOutlet have nothing to deal with memory management.

But because it is retain property, so you need to release it in dealloc.

So your code is correct.




回答3:


What you are doing is correct, and you generally shoudnt call release on the properties, since setting to nil does that already, however if you have a backing ivar to your property you can call release on that...




回答4:


There's a property and an instance variable behind the property. They both are called myImage, I presume (or you wouldn't be asking this question). You can free the instance in two ways - either release and nil the ivar, or just nil the property.

The compiler-generated setter for retained properties (like this one) works as following: release the currently held object reference (if any), assign the new value to the underlying ivar, retain it (if not nil). So when you assign nil to a property, it has the effect of releasing the current value and replacing it with nil.

To do that, use

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

To free an ivar, use

[myImage release];
myImage = nil;

This is functionally equivalent to the code above. Marginally faster. The thing you should be clear about is the distinction between properties and backing ivars. For that very reason, some people make a point of assigning different names to them, and synthesizing like this:

@synthesize MyImage = _MyImage;



回答5:


From Apple's documentation:

Legacy Patterns Prior to ARC, the rules for managing nib objects are different from those described above. How you manage the objects depends on the platform and on the memory model in use. Whichever platform you develop for, you should define outlets using the Objective-C declared properties feature.

The general form of the declaration should be:

@property (attributes) IBOutlet UserInterfaceElementClass *anOutlet;

Because the behavior of outlets depends on the platform, the actual declaration differs:

For iOS, you should use:

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

For OS X, you should use:

@property (assign) IBOutlet UserInterfaceElementClass *anOutlet;

You should then either synthesize the corresponding accessor methods, or implement them according to the declaration, and (in iOS) release the corresponding variable in dealloc.

This pattern also works if you use the modern runtime and synthesize the instance variables, so it remains consistent across all situations.




回答6:


First of all: consider switching to ARC if you aren't supporting iOS versions prior to 4.0.

Secondly, the best practice of writing dealloc methods says not to invoke setters. Instead, expressly release and nil your outlets:

[myImage release], myImage = nil;

Finally, when chaining together de-initialization methods like viewDidUnload, always call super's implementation after you do your own work.

The reason we nil out outlets in viewDidUnload is because sometimes views are unloaded when the system is under memory pressure. Since these outlets can be recreated easily, implementing viewDidUnload is a way to help performance, and in extreme situations, prevent your app from being forcefully terminated.

The reason we release properties in dealloc is to prevent memory leaks. So even though these two methods can look quite similar, they serve somewhat different purposes.




回答7:


I don't really get what you mean by "why can't I call the release method on myView"

Your code seems correct to me but by convention I usually prefer to release the iVar directly for a retained property I usually synthesize my property like this :

@synthesize myImage = _myImage;

And then you I release the iVar in the dealloc method

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

Anywhere else in the Controller I just go for the getter and setter (the dot convention)

Your viewDidUnload is correct.

By the way, if you're using ARC just declare your IBOutlet as a weak pointer. It will be automatically released in low memory situations and reloaded as soon as your view is loaded back again.

Hope this will help ;)



来源:https://stackoverflow.com/questions/9281266/how-to-release-iboutlet-defined-as-property

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!