confuced about releasing in viewDidUnload

Discussion in 'iOS Programming' started by MACloop, May 5, 2010.

  1. MACloop macrumors 6502

    Joined:
    May 18, 2009
    Location:
    Germany
    #1
    Hi,
    I have read the documentation about the use of the viewDidUnload method. I thought I did understand the meaning of this method, but after reading some more about it, I do feel confused. Is this the correct way to do this?

    1) I use retain with @propery in the .h file and @syntesize in the .m-file. I assign object with a value using self.object = something. In this case I would set self.object = nil; in the viewDidUnload method.

    2) I do not retain the object in the .h-file but I am allocing and init the object in the viewDidLoad method. In the dealloc method I have the [object release]; In the viewDidUnload method I also set [object release]; because the next time the view will appear, the object will be created in the viewDidLoad method

    3) What about IBOutlet objects also being retained by @property? Usually IBOutlet objects should be set to nil in the viewDidUnload method, right? Should they also be set to nil in the dealloc method?

    I got confused basically about releasing in the viewDidUnload and where to set objects to nil in the dealloc method. I have read alot posts/blogs etc where people say that release should not be done in the viewDidUnload method.

    Thanks in advance for helping me clear those things up!
    MACloop
     
  2. robbieduncan Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #2
    1) and 2) sound correct. I'm not sure about 3). My gut feeling is you should set them to nil but it is possible that if you call the method in the superclass it does this for you...
     
  3. MACloop thread starter macrumors 6502

    Joined:
    May 18, 2009
    Location:
    Germany
    #3
    Thanks alot for the answer! Well, #3 is sort of a special case. I assuem 1 and 2 are most common in use.
    MACloop
     
  4. MACloop thread starter macrumors 6502

    Joined:
    May 18, 2009
    Location:
    Germany
    #4
    Perhaps my confusion is not only about the viewDidUnload method :eek: but about the IBOutlet objects in general. I use this solution:

    Code:
    //in .h file
    IBOutlet Object *IBOutletObject;
    
    //in .m-file
    //I do not use self.IBOutletObject because there was no @property and/or @ synthesize set
    IBOutletObject = something;
    IBOutletObject.someVariable = somethingElse;
    My intention is to release that what I have retained. I did not retain anything and therefor I do not release anything. I have seen comments about this though, saying that an IBOutlet object always has to be released, because it will, in case of not using a @property (setter/getter) automatically be retained by one. I tried to set my IBOutlet object with @property and assign and that made my app crash when opening up the view for a second time. So, it seems to be true, that somehow a retain is done by default when you use a IBOutlet object. The question is - should I release the object in the dealloc? I have looked at the retaincount for the object and it does not increase everytime I go to the view. I have run my app in the leaks and it does not indicate on any leaking objects... If I should release the object even if I did not retain it - Is this the correct way to do this:

    In viewDidUnload:
    IBOutletObject = nil;

    in dealloc:
    [IBOutletObject release];

    MACloop
     
  5. PhoneyDeveloper macrumors 68030

    PhoneyDeveloper

    Joined:
    Sep 2, 2008
    #5
    In the case of the normal life cycle of outlets you should have a property for them and if it is a retaining property you should release the outlets. In dealloc you can release them, in viewDidUnload you should set the accessor to nil, which both releases and sets the ivar to nil.

    If you want to use an assign outlet that can also work. In that case you don't need to release the outlet or set it to nil. However, if viewDidUnload is called then the outlet will be invalid until viewDidLoad is called again. in most cases this is no problem. However if there is a chance that your view controller's code could be called from a notification or background thread or the network then you need to take care that the invalid outlets aren't messaged.

    The code you show is wrong. You need to

    [IBOutletObject release];
    IBOutletObject = nil;
     
  6. MACloop thread starter macrumors 6502

    Joined:
    May 18, 2009
    Location:
    Germany
    #6
    Thanks for the informative explanation! OK, should I always both release and set an object to be nil in the dealloc method? I read about this here and as I could see you only have to do that when programming for iPhone OS 2.x? So, I have to do this:

    Code:
    //in viewDidUnload
    IBOutletObject = nil;
    
    //in dealloc
    [IBOutletObject release];
    IBOutletObject = nil;
    ...
    [super dealloc];
    If I have an ordinary object with property and retain I do the following:
    Code:
    //in viewDidUnload
    self.object = nil;
    
    //in dealloc
    [object release];
    object = nil;//no ass.methods should be called in the dealloc accoring to apple doc?
    ...
    [super dealloc];
    Thanks in advance!
    MACloop
     
  7. PhoneyDeveloper macrumors 68030

    PhoneyDeveloper

    Joined:
    Sep 2, 2008
    #7
    "Best practice" is that in dealloc you only call release. There is no need to set to nil in almost all cases since the ivar will never be referenced again. However, setting to nil is benign, just normally useless.

    Also, don't use the property in dealloc because of possible side effects. Again this will normally be benign but it's better not to.

    The rules for all this were more complicated in 2.x because of defects in Apple's design, implementation, and documentation of this whole process. If you're not developing for 2.x then it doesn't matter.

    I'll admit that due to my app's history of being released for 2.x I have a releaseOutlets method that sets the outlets to nil using the property. I call releaseOutlets from both viewDidUnload and dealloc. It's not best practice any more to do it this way but it works without problems.
     
  8. MACloop thread starter macrumors 6502

    Joined:
    May 18, 2009
    Location:
    Germany
    #8
    Thank you very much for your explanation!
    MACloop
     

Share This Page