Memory management and ViewControllers

Discussion in 'iOS Programming' started by MACloop, Mar 17, 2010.

  1. MACloop macrumors 6502

    Joined:
    May 18, 2009
    Location:
    Germany
    #1
    Hello,
    I am not sure that I understand this alright.
    I have a tableViewController letting the user navigate by clicking one of the cells. In the didSelectRowAtIndexPath method, I do the following:
    Code:
    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    	vc= [[DetailedViewController alloc] initWithNibName:@"DetailedViewController" bundle:nil];
    	[self.navigationController pushViewController:vc animated:YES];
    	[vc release];
    }
    I have the following definition in the DetailedViewController.h file:
    Code:
    UISegmentedControl *choice;
    ...
    @property(nonatomic,assign) UISegmentedControl *choice;
    In the viewDidLoad in the DetailedViewController I define the following:
    Code:
    choice = [[UISegmentedControl alloc]initWithItems:items];
    	choice.segmentedControlStyle = UISegmentedControlStyleBar;
    	choice.selectedSegmentIndex = 0;
    	[choice addTarget:self action:@selector(segmentedControlValueChanged) forControlEvents:UIControlEventValueChanged];
    	self.navigationItem.titleView = choice;
    To enable the use of the segmentedControl:
    Code:
    - (void)segmentedControlValueChanged {
    	selectedUnit = choice.selectedSegmentIndex;
    	[self updateView];
    }
    
    
    - (void)updateView {
    	if (selectedUnit == 0) {
    		[aView setHidden:YES];
    		[anotherView setHidden:NO];
    	}
    	if (selectedUnit == 1) {
    		[aView setHidden:NO];
    		[anotherView setHidden:YES];
    	}
    }
    
    To release and free memory:
    Code:
    - (void)viewDidUnload {
    	// Release any retained subviews of the main view.
    	// e.g. self.myOutlet = nil;
    	self.aView = nil;
    	self.anotherView = nil;
    }
    
    - (void)dealloc {
        [super dealloc];
        [aView release];
        [anotherView release];
        [choice release];
    }
    The questions:
    1) Everytime when I push this view is the viewDidLoad called. Is the viewDidUnload and dealloc called when the user leaves the view ie. presses the backbutton?
    2) The definition of the segmentedControl is somthing that I have thought alot about. I use assign in the .h file. After that I create the object in the viewDidLoad. I release the object in the dealloc. This means that everytime I call the viewDidLoad, ie when the viewcontroller is pushed, a new choice object is created. Is this a godd solution? How could I do this differently? Is this leaking?

    Thanks in advance!
    MACloop
     
  2. PhoneyDeveloper macrumors 68030

    PhoneyDeveloper

    Joined:
    Sep 2, 2008
    #2
    Yes.

    No. dealloc is most likely called when the user taps the back button. viewDidUnload has a completely other purpose. When there is a memory warning the view controller unloads its view and sets its view property to nil. viewDidUnload is a notification that that process has occurred. You are expected to release and set to nil any ivars that are created in viewDidLoad. viewDidLoad and viewDidUnload can be called multiple times for a single view controller if there are memory warnings. If there are no memory warnings the viewDidUnload will not be called.

    Your overall strategy is ok but your implementation is defective. If there is a memory warning your code will leak the segmented control. Without a memory warning there should be no leak. What I would do is release the segmented control immediately after adding it to its superview. In viewDidUnload I would set its ivar to nil. It will then be released and dealloced in the case of a memory warning and then recreated in viewDidLoad.
     
  3. MACloop thread starter macrumors 6502

    Joined:
    May 18, 2009
    Location:
    Germany
    #3
    Thanks alot for you comments! The problem with the segmented control is that I need to detect which one of the buttons in the segemented control the user has clicked, later on in the code. This means, releasing it after adding it to the navigationBar will lead to a crash lateron in the app-flow. This does not seem to be very-effective-coding to me. Your advice to set it to nil in the viewDidUnload is good - I will try that out!
    Thanks again!
    MACloop
     

Share This Page