ObjC: How to proper implement a class that release itself?
I'm implementing a Login view and I need this view to be show at any time in my app. So to make it easier I create a class method called showLogin and when the view closes I want it to release itself so I did this:
@implementation LoginController
@synthesize releaseOnClose;
+ (void)showLogin {
LoginController *login = [[LoginController alloc] init];
login.releaseOnClose = YES;
[login show]; // Potential leak of login object
}
- (id)init {
if (self = [super initWithNibName:@"Login" bundle:[NSBundle mainBundle]]) {
releaseOnClose = NO;
}
return self;
}
- (void)show {
if (self.view.superview == nil) {
// show the view
}
}
- (void)btnCloseTouched {
[self.view removeFromSuperview];
if (releaseOnClose) {
[self release];
}
}
The Static Analyzer is telling me that there's a potential leak on showLogin, but in fact there isn't because I release the object in btnCloseTouched (don't worry about other features of a login view, for now it just open and close).
So I'd like to know how to avoid this potential leak message and how to proper i开发者_Go百科mplement this kind if class method to handle correctly the memory?
The Idea
A little more about what I thought. I wanted to call showLogin and it would exists until it's closed without the caller having to manage the instance.
The reason it's complaining about a leak is because you're allocating memory which is not released - for example:
LoginController *login = [[LoginController alloc] init];
And the way you're doing this seems all backwards - not really sure why you're instantiating a new object of LoginController within itself, and then releasing self in the attempt to release the new object? There has to be a much better way of doing it.
You'll have to release the instance of that one you allocated - self is not the instance of the new one you allocated (login).
Do the following when you're done with it:
[login release];
in your @implementation block you can declare the LoginController class like this:
@implementation LoginController
@synthesize releaseOnClose;
LoginController *mySingleLoginController;
then in your class method you can do:
+ (void)showLogin {
mySingleLoginController = [[LoginController alloc] init];
...
However as a design choice i wouldn't recommend this approach ...
Moszi
Why not create a new class for the login window (LoginView
) and then make sure that the class cleans up after itself in dealloc
. Then you can make a new instance of that class when you need it, and when you remove it there should be no memory leak.
Why not do it the ordinary way and let the instance that initialized the class release it, or put it in an autorelease pool?
I don't see the benefit of having a class that removes and releases itself when some action happens. What's your motivation for doing it this way?
精彩评论