Advertise Mobile SDKs Books Events Forum News Social Networking Support Us
Follow @iphonedevsdk on Twitter

Mockup & CodeGen, iPhone & iPad
($9.99)

Make your own iPhone apps
and run them live!
(free)

Manu
($0.99)

Want your application or service advertised on iPhone Dev SDK?

Go Back   iPhone Dev SDK Forum > iPhone SDK Development Forums > iPhone SDK Development

Reply
 
LinkBack Thread Tools Display Modes
Old 07-21-2009, 02:33 PM   #1 (permalink)
New Member
 
Join Date: Feb 2009
Posts: 11
Exclamation Releasing view controllers

I'm having problems releasing memory for view controllers, and hope someone can save my sanity! The app is really quite big, so for simplicity, I am adding code that just illustrates the problem.

I have an app that contains multiple views (each with corresponding view controller).

I have a MainViewController (inherits from UIViewController) which has a property for each sub-view controller:

Code:
@interface MainViewController : UIViewController {
    SubViewController1 *subViewController1;
    SubViewController2 *subViewController2;
    SubViewController3 *subViewController3;
}

@property (nonatomic, retain) SubViewController1 *subViewController1;
@property (nonatomic, retain) SubViewController2 *subViewController2;
@property (nonatomic, retain) SubViewController3 *subViewController3;

-(void) openSubView1;
-(void) openSubView2;
-(void) openSubView3;
-(void) closeSubView1;
-(void) closeSubView2;
-(void) closeSubView3;

@end
In the implementation of MainViewController, I have the methods for opening and closing the subviews:

Code:
- (void) openSubView1 {
    self.subViewController1 = [[SubViewController1 alloc] init];
    [self.view insertSubview:self.subViewController1.view atIndex:0];
}

- (void) closeSubView1 {
    [self.subViewController1.view removeFromSuperview];
    [self.subViewController1 release];
    self.subViewController1 = nil;
}
The app delegate has a property for the MainViewController, so the calls to the closeSubViewX methods are made via appDelegate.mainViewController from the relevant sub view controller implementation.

On the surface the functionality works as expected with the sub view showing and disappearing... however, the SubViewControllerX objects don't get released, and the retain count increases by 1 every time I call the openSubViewX methods.

The other interesting thing to note is that dealloc IS getting called on the SubViewControllerX - so I'm confused as to why the retain count doesn't reduce.

I really hope someone can help guide me on where I may be going wrong - thanks in advance!
iGrump is offline   Reply With Quote
Old 07-21-2009, 02:52 PM   #2 (permalink)
Use [code] tags please
 
Join Date: Jun 2009
Location: Jacksonville, FL
Posts: 362
Default

The call to self.subViewController is also bumping the retain count so after alloc/initial and the property (retain is set on the prop) definition the count is 2.
timle8n1 is online now   Reply With Quote
Old 07-21-2009, 03:09 PM   #3 (permalink)
Registered Member
 
Join Date: Jul 2009
Location: Philadelphia, PA
Posts: 154
Default

I believe you can release the view after inserting it, because views retain their subviews. Does that work?
dancriel is offline   Reply With Quote
Old 07-21-2009, 03:56 PM   #4 (permalink)
Registered Member
 
Join Date: Nov 2008
Posts: 791
Default

I don't see a problem... 3 retains, 3 releases (with my noob objc eyes). Your dealloc method is being called, so what's wrong ?
nobre84 is offline   Reply With Quote
Old 07-21-2009, 05:28 PM   #5 (permalink)
New Member
 
Join Date: Feb 2009
Posts: 11
Unhappy Thanks.. but no joy

Quote:
timle8n1: The call to self.subViewController is also bumping the retain count so after alloc/initial and the property (retain is set on the prop) definition the count is 2.
Quote:
dancriel: I believe you can release the view after inserting it, because views retain their subviews. Does that work?
- Thank you for replying both. I tried removing the property altogether and replacing the methods with

Code:
- (void) openSubView1 {
    SubViewController1 *svc1 = [[SubViewController1 alloc] init];
    [self.view insertSubview:svc1.view atIndex:0];
    [svc1 release];
}

- (void) closeSubView1 {
    [self.view.subviews objectAtIndex:0 removeFromSuperview];
}
When I ran this, the xib view did not appear in view, but yet the retain count for the view controller still increased!

If I comment out the [svc1 release]; line, the view appears (but of course still retains!)


Quote:
nobre84: I don't see a problem... 3 retains, 3 releases (with my noob objc eyes). Your dealloc method is being called, so what's wrong ?
I agree! I can't understand why this problem is happening!!

Any further ideas anyone? (I am beginning to think I'm using Instruments incorrectly... !!!)
iGrump is offline   Reply With Quote
Old 07-21-2009, 06:19 PM   #6 (permalink)
Use [code] tags please
 
Join Date: Jun 2009
Location: Jacksonville, FL
Posts: 362
Default

Quote:
Originally Posted by iGrump View Post
When I ran this, the xib view did not appear in view, but yet the retain count for the view controller still increased!
Hold up the view you are expecting to see is built in IB? I don't see you loading it from the XIB? When you do

SubViewController1 *svc1 = [[SubViewController1 alloc] init];

you are not loading a view from a xib. You need to use

- (id)initWithNibNameNSString *)nibName bundleNSBundle *)nibBundle

to init a UIViewController with a UIView loaded from a XIB. I suspect if it was working before you had already wired something to the property subViewController1 and we are not seeing the whole picture here.
timle8n1 is online now   Reply With Quote
Old 07-21-2009, 06:29 PM   #7 (permalink)
Emphasizing Fundamentals
 
BrianSlick's Avatar
 
Join Date: Jul 2009
Location: NoVA / DC Area
Age: 36
Posts: 7,129
Default

The alloc/init is +1. Assigning it to the property is another +1. Your retain count is 2, but you only have a single release.

A couple of things to do/not do. For one, don't alloc/init in the same command where you make the assignment. Create the object, assign it, then release it. Also, consider more of a lazy-loading approach. You sort of have one with your methods, but you could take it a step further. Ex:

Code:
- (void) openSubView1 
{
   if ([self subViewController1] == nil)
   {
      SubViewController1 *svc1 = [[SubViewController1 alloc] init];
      [self setSubViewController1: svc1];
      [svc1 release], svc1 = nil;
   }
   [[self view] insertSubview:[[self subViewController1] view] atIndex:0];
}
When you are done with it, just set the property to nil if you really don't want it around anymore.
Code:
- (void) closeSubView1 {
    [[[self subViewController1] view] removeFromSuperview];
    [self setSubViewController1: nil];
}
Release it in dealloc like you would with any property.

Bonus points for freeing it in the event of low memory:

Code:
- (void)didReceiveMemoryWarning 
{
   [self setSubViewController1: nil];
   [super didReceiveMemoryWarning]
}
BrianSlick is offline   Reply With Quote
Old 07-22-2009, 10:46 AM   #8 (permalink)
New Member
 
Join Date: Feb 2009
Posts: 11
Smile

timle8n1 & BrianSlick

Thanks for taking the time to reply.

I have started a new project from scratch and implemented things following everyone's feedback here - and now have a successful release of memory.

Not sure why I couldn't get this to happen on the old project and it's frustrating to have to start again - but it proves the theories are sound, so I am more than happy!

Thanks again to all who responded.
iGrump is offline   Reply With Quote
Reply

Bookmarks

Tags
memory management, view controllers

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On



» Advertisements
» Online Users: 268
20 members and 248 guests
@sandris, AdamL, ADY, Dani77, diyora, FAED, F_Bryant, GHuebner, HDshot, headkaze, mer10, Oral B, prchn4christ, Rudy, smithdale87, Thompson22, timle8n1, Touchmint, twerner, vigu360
Most users ever online was 1,187, 10-11-2011 at 08:09 AM.
» Stats
Members: 158,880
Threads: 89,228
Posts: 380,749
Top Poster: BrianSlick (7,129)
Welcome to our newest member, @sandris
Powered by vBadvanced CMPS v3.1.0

All times are GMT -5. The time now is 12:56 PM.
Powered by vBulletin® Version 3.8.0
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.3.0