Can I skip creating a separate pointer when setting up my viewController?

Why do I need to create a pointer just to allocate memory, and then immediately release it?

In other words, can I just do this:

self.viewController = [[HelloWorldViewController alloc] initWithNibName:@"HelloWorldViewController" bundle:[NSBundle mainBundle]]; 

instead of this:

 HelloWorldViewController *newViewController = [[HelloWorldViewController alloc] initWithNibName:@"HelloWorldViewController" bundle:[NSBundle mainBundle]]; self.viewController = newViewController; [newViewController release]; 

[EDIT]

To provide a wider context for my question: (in @implementation @interface HelloWorldAppDelegate: NSObject <UIApplicationDelegate>)

 @synthesize window=_window; @synthesize viewController=_viewController; 

...

 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { HelloWorldViewController *newViewController = [[HelloWorldViewController alloc] initWithNibName:@"HelloWorldViewController" bundle:[NSBundle mainBundle]]; self.viewController = newViewController; [newViewController release]; self.window.rootViewController = self.viewController; [self.window makeKeyAndVisible]; return YES; } 

...

 - (void)dealloc { [_window release]; [_viewController release]; [super dealloc]; } 

So, in the didFinish ... method, can I use the short version above, or will it leak?

[SECOND EDIT]

It seems that I just canโ€™t give enough information. I always hesitate to post a huge pile of code. I have this in HelloWorldAppDelegate.h:

 @property (nonatomic, retain) IBOutlet HelloWorldViewController *viewController; 

So correct me if I am wrong. Given the viewController declaration in the header file, if I use the shortcut method (in the first code snippet above), the program leaks. The object counter is incremented once with alloc, and then held the second time, and then decremented once per release, creating a +1 grid on the pointer pointer counter.

+4
source share
2 answers

You need to free the selected object, or you will lose a memory leak. The purpose of self.viewController (presumably) preserves the value of new-alloc'd HelloWorldViewController , so you have two "claims" on the object: one from your call to alloc and one from retain , but you "will actually not use it anymore under the name newViewController , so you will newViewController this particular requirement by calling release .

A โ€œlongโ€ form using a temporary variable is actually the right way to do this. Sending release to the result of accessing the resource: [self.viewController release]; immediately after installing it, it most likely will work, but incorrectly (and will generate a compiler warning for the latest LLVM versions).

This can also be done:

 self.viewController = [[[HelloWorldViewController alloc] initWithNibName:@"HelloWorldViewController" bundle:[NSBundle mainBundle]] autorelease]; 

which says: "I created this thing to use it for a short time, but I will not need it outside this quick call stack, so go ahead and let it go for me later."

If viewController does not retain its property, then this is all a moot point, and you should not send release to the new view controller, as it will be freed before using it.

UPDATE: your extended question doesn't change anything *. If you do not submit release before newViewController goes out of scope, you will get a leak. ** How it works, any object (A, B, C) that should use the object X, and therefore takes care to keep it around, sends retain to X. When you alloc object, it suggested that you need it use. If any of A, B or C no longer needs X, it sends release to X, thereby saying: "X can be freed, and that will not affect me." You need to balance the number of claims that you make (using retain , alloc , copy / mutableCopy or new ) on the object with the number of failures you made (sending release or autorelease ), or you will either have a leak or an accidental release at your fingertips.

Now I will give you a link to documents, but donโ€™t get annoyed, this is just one page that you need to read and internalize: Cocoa Basic Rule Memory Management .


* Actually, you left only a part that could change the answer, namely yours

 @property () HelloWorldViewController * viewController; 

ads. If โ€œsaveโ€ is indicated in these parentheses, then when this property is set, the application delegate sends retain to the passed object. If it says "assign" or the parentheses do not exist, then, as I said, you should not send release this object.

** Note for any pedants who are watching: you could, of course, send release twice to the viewController at some point, but this is worse than a leak.

+3
source

Yes you can do it. Except that you need to free self.viewController so that the save counter is 1 at the end of the fragment.

Let it be counted. At distribution, the number of releases is 1. Assigning it to self.viewController (provided that this property with retain behavior) increases it to two. Releasing it at the end of the second fragment makes it another 1. The idea is that you completely free it in the dealloc of the current class, whatever that is.

The only wrinkle is that releasing an object variable assumes what you did with it, and here you need to go, freeing self.viewController, but using it later. Someone smelly.

+2
source

All Articles