bubbles
bubbles

Reputation: 881

Understanding reference counting/memory and properties

My question is - Could you please correct me if im wrong? Thanks!

The simplest example i can think of is creating an app from scratch. Delete the MainWindow nib file etc.

// .h file of appDelegate
UIWindow* window_;

@property UIWindow* window;

// .m appDelegate
@synthesize window = window_
[window_ release] // dealloc method

lets say in Application did finish launching method

{
// window is currently nil with a reference count of 0.

window_ [[UIWindow alloc] initWithFrame: [[UIScreen mainScreen] bounds]]; // window_ has a reference count of 1

MyViewController* myVC = [[MyViewController alloc] initWithNibName:nil bundle nil]; // myVC has a reference count of 1

UINavigationController* navCon = [[UINavigationController alloc] initWithRootViewController:myVC] // navCon reference count 1, myVC reference count of 2

//way 1
self.window.rootViewController = navCon; // navcon has a reference count still 1. however since self.window.rootViewController was nill, all is nice and dandy. if however, self.window.rootViewController was not nil there would be a memory leak
[myVC release]; // brings myVC down to 1, all is good and well;
[self.window makeKeyAndVisible];

//way 2
[self.window setRootViewController: navCon]; // releases self.window setRootViewController 1 to 0, then retains navController which brings it back to 1
[myVCrelease]; //onece again brought back to one
[navCon release]; //since it's reference count is 2 thanks to setRootViewController
[self.window.makeKeyAndVisible].
}

when will navCon ultimately released? When the app closes? Or is there something going on behind the scenes? Is my way of programming similar to your style? Should i be using a lot of self.window instead window_? should i be using a lot of setProperty instead of = ? Thank you for your time!

}

Upvotes: 2

Views: 325

Answers (3)

Micah Hainline
Micah Hainline

Reputation: 14437

A few points:

Objects are released immediately when the retain count associated with them reaches zero.

Properties handle retaining and releasing, and you absolutely should be using properties rather than the raw variables associated with them (use self.window instead of _window).

Don't try to keep track of the raw counts, instead just manage the memory responsibly. So for instance, you can release your myVC whenever you hand it off to the navigation controller, not when the retain count has been incremented.

It will also be easier for you if you just autorelease instead of manually releasing. There's less to worry about. autorelease is very simple, it just calls release "later", which is actually when the run loop is executed again. Basically it lets you be more concerned with the code and less with the memory management. Anything not held on to by someone else by the end of the block will be released for you.

This also follows the standards suggested by Google for Objective C. See http://google-styleguide.googlecode.com/svn/trunk/objcguide.xml.

Upvotes: 1

zaph
zaph

Reputation: 112875

ivar management

All ivars should be created with properties. If the ivar is only for local class use it should be declared in a class extension.

All properties should be synthesized with shadow ivars with a leading underscore.

All IBOutlets should have retain properties.

All BOOL properties should have an is* getter.

All delegate properties should be assign (or weak if under ARC).

Examples:

@property (nonatomic, retain) NSString *exampleString;
@property (nonatomic, retain) IBOutlet UILabel *exampleLabel;
@property (nonatomic, assign, getter=isExampleBool) BOOL exampleBool;

@synthesize exampleString = _exampleString;
@synthesize exampleLabel = _exampleLabel;
@synthesize exampleBool = _exampleBool;

init, dealloc, viewDidUnload

In the init method

  • Property ivars should be set directly, not through the property.

  • Any ivars that should not default to nil, 0 or NO should be set or created.

In the dealloc method:

  • All ivar objects should be released, not setting their value to nil through the property

  • All delegate objects should be set to nil.

In viewDidUnload

  • All IBOutlets should be released and set to nil.

Upvotes: 0

dasdom
dasdom

Reputation: 14073

I would release myVC right after the init of the navigation controller:

UINavigationController* navCon = [[UINavigationController alloc] initWithRootViewController:myVC]
[myVC release];

In the first way you are leaking navCon.

I prefer the second way.

You should always use the properties.

Upvotes: 0

Related Questions