Helping understand management of Views (& release)

Discussion in 'iOS Programming' started by dantastic, Mar 8, 2011.

  1. dantastic macrumors 6502

    dantastic

    Joined:
    Jan 21, 2011
    #1
    I just came across this *problem* as I created a UIView with a date picker and a uitoolbar. I'd have the view slide up and down the screen. Not exactly sure how to go about this I found some code on dem internets and did what any budding coder does, cmd+c, cmd+v.

    After some tuning to suit my needs the code works perfectly.

    Being a good memory citizen I went on the usual quest to make sure there were no lose ends when I started asking myself - Why does this work???

    Code:
    @interface {
    	UIDatePicker *datePicker;
    	UIView *pickerView;
    }
    @property (nonatomic, retain) UIDatePicker *datePicker;
    @property (nonatomic, retain) UIView *pickerView;
    
    ...
    
    - (void) loadDatePicker {
    
    	datePicker = [[UIDatePicker alloc] initWithFrame:CGRectMake(0, 44, 320, 250)];  
    	[datePicker addTarget:self
    	               action:@selector(changeDate:) forControlEvents:UIControlEventValueChanged];
        ...
    	UIToolbar *toolBar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, 320, 44)];
       ...
    	pickerView = [[UIView alloc] initWithFrame:CGRectMake(0, 480, 320, 260)];
    
    	[pickerView addSubview:toolBar];
    	[pickerView addSubview:datePicker];
    	[toolBar release];
    	[datePicker release];
    	[self.view addSubview:pickerView];
    	[pickerView release];
    
    So far so good, I get what is happening here. I clean up all the objects I allocate and I simply dump a view into the subview. In my understanding, the contents of this subview should be somewhat orphaned from the objects that was used to create them? Here's what I don't get:
    Code:
    - (void) changeDate:(id)sender {
    	// should this not crash my app??
    	cellLabel.text =  [datePicker date];	
    }
    
    If I have already released 'datePicker', howcome the above works?
    What is the correct way of doing this?
     
  2. robbieduncan Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #2
    This is the problem with copy/pasting code: you have no idea what you have, how it works and have learnt nothing. The answer, in this case, is that when you add a view to another view using addSubview the superview retains it's children.
     
  3. dantastic thread starter macrumors 6502

    dantastic

    Joined:
    Jan 21, 2011
    #3
    Ok, so even though released the reference to 'datePicker' is still perfectly valid until I call my function to clean up the subviews:

    Code:
      ...
    		if (subview.tag == 78) {
    			for (UIView *subSubview in [subview subviews]) {
    				[subSubview removeFromSuperview];
    			}
    			[subview removeFromSuperview];
    		}
    
    Will this properly get rid of the references for me or do I have to do anything else as well?

    Should I be releasing where I am or should I release when I remove the subviews?
     
  4. robbieduncan Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #4
    Removing the subview will cause the parent view to release it. If you have a variable pointing at it (and this release by the parent causes the retain count to drop to 0) then your pointer will end up pointing at freed memory: bad.
     
  5. dantastic thread starter macrumors 6502

    dantastic

    Joined:
    Jan 21, 2011
    #5
    Right, So I'm actually OK so.

    I've an OK button that when called slides the uiview out of view and then removes all subviews. I don't reference any of these fellas again until a new instance of the entire viewcontroller is allocated.

    Cheers mate!
     

Share This Page