Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

MACloop

macrumors 6502
Original poster
May 18, 2009
393
0
Germany
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
 

robbieduncan

Moderator emeritus
Jul 24, 2002
25,611
893
Harrogate
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...
 

MACloop

macrumors 6502
Original poster
May 18, 2009
393
0
Germany
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...

Thanks alot for the answer! Well, #3 is sort of a special case. I assuem 1 and 2 are most common in use.
MACloop
 

MACloop

macrumors 6502
Original poster
May 18, 2009
393
0
Germany
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
 

PhoneyDeveloper

macrumors 68040
Sep 2, 2008
3,114
93
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;
 

MACloop

macrumors 6502
Original poster
May 18, 2009
393
0
Germany
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;

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
 

PhoneyDeveloper

macrumors 68040
Sep 2, 2008
3,114
93
"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.
 

MACloop

macrumors 6502
Original poster
May 18, 2009
393
0
Germany
"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.

Thank you very much for your explanation!
MACloop
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.