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 06-30-2009, 08:22 PM   #1 (permalink)
New Member
 
Join Date: Jun 2009
Posts: 19
Default iPhone Objective-C convention question

I'm just starting iphone development and am getting my head around objective-C, the framework, etc.. Why does all sample code follow the following pattern:
Code:
    UINavigationController *aNavigationController = [[UINavigationController alloc] initWithRootViewController:rootViewController];
    self.navigationController = aNavigationController;
    [aNavigationController release];
where the object is first created, then assigned to the property, and then released, rather than:

Code:
self.navigationController = [[UINavigationController alloc] initWithRootViewController:rootViewController];
which seems simpler.

Thanks
farhadf is offline   Reply With Quote
Old 06-30-2009, 08:53 PM   #2 (permalink)
jsd
at this moment
 
Join Date: Mar 2009
Location: San Francisco, CA
Posts: 900
Default

Quote:
Originally Posted by farhadf View Post
I'm just starting iphone development and am getting my head around objective-C, the framework, etc.. Why does all sample code follow the following pattern:
Code:
    UINavigationController *aNavigationController = [[UINavigationController alloc] initWithRootViewController:rootViewController];
    self.navigationController = aNavigationController;
    [aNavigationController release];
where the object is first created, then assigned to the property, and then released, rather than:

Code:
self.navigationController = [[UINavigationController alloc] initWithRootViewController:rootViewController];
which seems simpler.

Thanks
The second version is a memory leak. You alloc/init the object, which gives you a retained copy, and then you assign it somewhere else without releasing it. You could do it in one line with an autorelease but in general it's better to do an explicit release as soon as you're done with something. If the object could be released immediately but you've put autorelease on it, the object will stick around until the next time the autorelease pool drains. Probably not a big deal most of the time, but the iPhone is very tight on memory so why not squeeze every last little drop of space out of it?
jsd is offline   Reply With Quote
Old 07-01-2009, 12:02 AM   #3 (permalink)
New Member
 
Join Date: Jun 2009
Posts: 19
Default

Quote:
Originally Posted by jsd View Post
The second version is a memory leak. You alloc/init the object, which gives you a retained copy, and then you assign it somewhere else without releasing it. You could do it in one line with an autorelease but in general it's better to do an explicit release as soon as you're done with something. If the object could be released immediately but you've put autorelease on it, the object will stick around until the next time the autorelease pool drains. Probably not a big deal most of the time, but the iPhone is very tight on memory so why not squeeze every last little drop of space out of it?
Hmm, the subtleties of memory management in objective-c. In the first case, when the assignment is done, the property will (likely) have a retain directive, so the count goes up to 2, but then when we release it, it goes back down to 1 (only for the property), and eventually goes to 0 in the dealloc, I imagine. Is this correct?

What would happen in the second case? Would it get a retain count of 2 upon assignment, then get stuck with a count of 1 afterward the dealloc?

thx
farhadf is offline   Reply With Quote
Old 07-01-2009, 07:56 AM   #4 (permalink)
Registered Member
 
Join Date: Jun 2009
Location: Ypsilanti, Michigan
Age: 63
Posts: 1,526
Default

Quote:
Originally Posted by farhadf View Post
Hmm, the subtleties of memory management in objective-c. In the first case, when the assignment is done, the property will (likely) have a retain directive, so the count goes up to 2, but then when we release it, it goes back down to 1 (only for the property), and eventually goes to 0 in the dealloc, I imagine. Is this correct?

What would happen in the second case? Would it get a retain count of 2 upon assignment, then get stuck with a count of 1 afterward the dealloc?

thx
You've got it exactly right!
RLScott is offline   Reply With Quote
Old 07-01-2009, 11:24 AM   #5 (permalink)
jsd
at this moment
 
Join Date: Mar 2009
Location: San Francisco, CA
Posts: 900
Default

Quote:
Originally Posted by RLScott View Post
You've got it exactly right!
No he doesn't. Back to Cocoa memory management school for both of you!

Quote:
Hmm, the subtleties of memory management in objective-c. In the first case, when the assignment is done, the property will (likely) have a retain directive, so the count goes up to 2, but then when we release it, it goes back down to 1 (only for the property), and eventually goes to 0 in the dealloc, I imagine. Is this correct?

What would happen in the second case? Would it get a retain count of 2 upon assignment, then get stuck with a count of 1 afterward the dealloc?
Forget about the property and whether or not it retains for a minute. The goal of Cocoa memory management is to balance your retains and releases. Alloc gives you an object with a retain count of 1 so it is up to YOU to release (or autorelease) it. Since you didn't do that, it doesn't matter whether or not the property retains it - you still have a count of 1 that has to be dealt with.

The retain count won't go to 0 in the dealloc - retain counts are never automatically decremented like that. The only time the retain count goes down is when you do a release or autorelease. In fact, dealloc is not even called until the retain count of the object hits zero.

I know it's a little confusing at first but you will get the hang of it. Just stick with it and don't get discouraged. I certainly made my fair share of mistakes!

Very simple rules for memory management in Cocoa
jsd is offline   Reply With Quote
Old 07-01-2009, 12:34 PM   #6 (permalink)
Registered Member
 
Join Date: Nov 2008
Posts: 188
Default

Quote:
Originally Posted by jsd View Post
No he doesn't. Back to Cocoa memory management school for both of you!



Forget about the property and whether or not it retains for a minute. The goal of Cocoa memory management is to balance your retains and releases. Alloc gives you an object with a retain count of 1 so it is up to YOU to release (or autorelease) it. Since you didn't do that, it doesn't matter whether or not the property retains it - you still have a count of 1 that has to be dealt with.

The retain count won't go to 0 in the dealloc - retain counts are never automatically decremented like that. The only time the retain count goes down is when you do a release or autorelease. In fact, dealloc is not even called until the retain count of the object hits zero.

I know it's a little confusing at first but you will get the hang of it. Just stick with it and don't get discouraged. I certainly made my fair share of mistakes!

Very simple rules for memory management in Cocoa
+1
Done right, there is minimal dependency between classes and methods for the correct memory behaviour.
retains and releases should be balanced within the method (or class in the case of instance variables).

Just imagine someone else is writing all the other methods in your project, and you have zero contact with this person, how do you ensure correct memory management? If each person follows the rules, they don't need to communicate where they are doing retains/releases, and correct memory management ensues. This is how the Cocoa framework is written.
jsonli is offline   Reply With Quote
Old 07-01-2009, 12:42 PM   #7 (permalink)
New Member
 
Join Date: Jun 2009
Posts: 19
Default

Quote:
Originally Posted by jsonli View Post
+1
Done right, there is minimal dependency between classes and methods for the correct memory behaviour.
retains and releases should be balanced within the method (or class in the case of instance variables).

Just imagine someone else is writing all the other methods in your project, and you have zero contact with this person, how do you ensure correct memory management? If each person follows the rules, they don't need to communicate where they are doing retains/releases, and correct memory management ensues. This is how the Cocoa framework is written.
I should have been more precise in my original response. What I meant is that in an object dealloc, one typically releases one's properties. But what you both indicate makes better sense - it's actually irrelevant. Any individual method needs to track its own allocations and release them. That's probably the best way to think about it.

I thought autorelease marked the item for garbage collection at the later time, and GC is not available on the iphone.

I'm coming from programming ruby the last couple of years - life used to be so easy....
farhadf is offline   Reply With Quote
Old 07-01-2009, 12:55 PM   #8 (permalink)
jsd
at this moment
 
Join Date: Mar 2009
Location: San Francisco, CA
Posts: 900
Default

Quote:
I thought autorelease marked the item for garbage collection at the later time, and GC is not available on the iphone.
not quite. autorelease just marks an object for a release action "at some point in the future." the future point is typically the next time the run loop is entered, which is usually pretty quick. (i'm qualifying this heavily with words like "typically" and "usually" because you can do things to interfere with this, but most of the time you won't.)

garbage collection, the way most people think of it, is completely automatic and happens outside the control of the programmer. autorelease is under your control.

my advice would be to only use autorelease when you are returning an object that you alloced. eg:

Code:
- (someobject *)myMethodReturningObject {
    someobject *myobject = [[someobject alloc] init];
    [myobject doSomethingToSetItUp];
    [myobject autorelease];
    return myobject;
}
As you can see here, you've alloced the object, so it is your responsibility to provide a balancing release message. However, you want to return it to another method, so you can't just release it, or it would be lost before the other method got it. Autorelease is your friend in this case.

Quote:
I'm coming from programming ruby the last couple of years - life used to be so easy....
tell me about it - i was doing perl and php for the last 10 years. cocoa was quite a kick in the pants, took me about 6-8 weeks to get comfortable with it.
jsd is offline   Reply With Quote
Old 07-01-2009, 01:26 PM   #9 (permalink)
Pro. Game Developer
iPhone Dev SDK Supporter
 
Join Date: Feb 2009
Location: żLa Islas Hermosas?
Posts: 2,178
Default

Quote:
Originally Posted by farhadf View Post
What would happen in the second case? Would it get a retain count of 2 upon assignment, then get stuck with a count of 1 afterward the dealloc?
Quote:
Originally Posted by RLScott View Post
You've got it exactly right!
Quote:
Originally Posted by jsd View Post
No he doesn't. Back to Cocoa memory management school for both of you!
Hmm... I believe the "second case" is the one quoted below, so unless I'm missing something, I think the "you've got it exactly right" assessment is indeed correct.

Quote:
Originally Posted by farhadf View Post
Code:
self.navigationController = [[UINavigationController alloc] initWithRootViewController:rootViewController];
__________________
~~ Word Flurry ~~ App Store / Website / Facebook
Kalimba is offline   Reply With Quote
Old 07-01-2009, 01:30 PM   #10 (permalink)
Registered Member
 
Join Date: Nov 2008
Posts: 188
Default

Quote:
Originally Posted by Kalimba View Post
Hmm... I believe the "second case" is the one quoted below, so unless I'm missing something, I think the "you've got it exactly right" assessment is indeed correct.
Well, it does have an extra retain on it, but it also would never get to dealloc with a retain count of 1.
jsonli is offline   Reply With Quote
Old 07-01-2009, 01:35 PM   #11 (permalink)
jsd
at this moment
 
Join Date: Mar 2009
Location: San Francisco, CA
Posts: 900
Default

Quote:
Originally Posted by Kalimba View Post
Hmm... I believe the "second case" is the one quoted below, so unless I'm missing something, I think the "you've got it exactly right" assessment is indeed correct.
The line of code you quoted generates an object with a retain count of 1. It *might* have a retain count of 2 after being assigned to self.navigationController - but you don't know that. You're not supposed to know, or even need to know. The original poster said it generated a retain count of 2, which is possibly wrong (the assignment might not do a retain at all, or it might assign it to other things, leading to a count of more than 2, who knows what setNavigationController is doing - again, irrelevant). The important principle to take away is that you shouldn't think about what anybody else is doing with your stuff. You need to balance your own retains and releases, and in this case, they aren't.
jsd is offline   Reply With Quote
Old 07-01-2009, 01:36 PM   #12 (permalink)
Pro. Game Developer
iPhone Dev SDK Supporter
 
Join Date: Feb 2009
Location: żLa Islas Hermosas?
Posts: 2,178
Default

Quote:
Originally Posted by jsonli View Post
Well, it does have an extra retain on it, but it also would never get to dealloc with a retain count of 1.
Ah... I read "...get stuck with a count of 1..." and my mind stopped reading. Right, having a retain count of 1 (or greater) "after the dealloc" makes no sense, as the dealloc will not be called until the release method drops the retain count to 0.

Nevermind me...
__________________
~~ Word Flurry ~~ App Store / Website / Facebook
Kalimba is offline   Reply With Quote
Old 07-02-2009, 08:30 AM   #13 (permalink)
Registered Member
 
Join Date: Jun 2009
Location: Ypsilanti, Michigan
Age: 63
Posts: 1,526
Default

Quote:
Originally Posted by jsd View Post
No he doesn't. Back to Cocoa memory management school for both of you!
None of your subsequent explanation contradicts anything farhadf said. He did have it right, as his subsequent clarifications shows. I understood what object he was referring to when he said "eventually goes to zero in the dealloc", and that he as not assuming the release was automatic, but was part of the usual explicit releases that a programmer does in a dealloc method.

Robert Scott
Ypsilanti, Michigan
RLScott is offline   Reply With Quote
Old 07-21-2009, 01:28 PM   #14 (permalink)
Registered Member
 
Join Date: Sep 2008
Posts: 29
Default Tutorial video - memory, auto release, properties

Hey, I just posted a video of my training material on the basics of memory management for iPhone, which includes auto release pool and properties:

Memory Management Basics Tutorial Video | markjnet
markofjohnson is offline   Reply With Quote
Reply

Bookmarks

Tags
objective-c, style

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: 263
22 members and 241 guests
ADY, AragornSG, bookesp, chillyh, dacapo, Dani77, Davey555, Desert Diva, Dominus, glenn_sayers, HemiMG, JasonR, LEARN2MAKE, M.A.S., marshusensei, mer10, nobre84, Oral B, prchn4christ, Raggou, Rudy, themathminister
Most users ever online was 1,187, 10-11-2011 at 08:09 AM.
» Stats
Members: 158,885
Threads: 89,230
Posts: 380,765
Top Poster: BrianSlick (7,129)
Welcome to our newest member, bookesp
Powered by vBadvanced CMPS v3.1.0

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