views:

68

answers:

5

I am a bit lost with the memory management. I've read that you should release whenever you alloc. But when you get an instance without the alloc, you shouldnt release.

What about this situation, just need to know If I was coding correctly. I'm still new on iphone dev.

I have a class CustomerRepository it has a method

- (MSMutableArray *) GetAllCustomers() {

  MSMutableArray *customers = [[MSMutableArray alloc] init];

  Customer *cust1 = [[Customer alloc] init];
  cust1.name = @"John";

  Customer *cust2 = [[Customer alloc] init];
  cust2.name = @"Tony";

  [customers addOjbect:cust1];
  [customers addOjbect:cust2];

  [cust1 release];
  [cust2 release];

  return customers;

}

Then I have a UIViewController

- (void) LoadCustomers() {

      CustomerRepository *repo = [[CustomerRepository alloc] init];

      MSMutableArray *customers = [repo GetAllCustomers];          

      // Iterate through all customers and do something

      [repo release];

} 

So in this scenario ... the MSMutableArray will never be release? Where should it be release?

A: 

The customers array should be released after you are done iterating it. You delegated the creation of the array to your repo object but your LoadCustomers method owns the array.

Another approach would be to have your CustomerRepository expose an allCustomers property. You could lazily initialize the array in your getter and then release the array when the CustomerRepository is released. That would keep your calls to alloc and release in the same object.

highlycaffeinated
A: 

it should be released in your view controller, LoadCustomers() since you are allocing it in the method you are calling, it is still owned by YOU.

Jesse Naugher
+2  A: 

Whenever you create and return an object from a method or function, that object should be autoreleased. The exceptions are when the method starts with Create or New (or Alloc, obviously), or when the object is being cached within the method.

The other answers which suggest releasing it in LoadCustomers are incorrect, because GetAllCustomers does not imply a transfer of ownership like CreateCustomersArray or NewCustomersArray would. However, you can't release the object in GetAllCustomers either because then the object would be deallocated before returning it. The solution is autorelease.

kperryua
Good point on the naming of the method not implying the transfer of ownership of the object.
highlycaffeinated
So my only option is to use autorelease correct
pdiddy
When the methods starts with Create, how does it transfer ownership?
pdiddy
It's just a convention to help you implicitly know the ownership implications of a method without having to look at any documentation. You'll find that this convention is enforced by the clang static analyzer, but the compiler itself doesn't pay any attention to it.
kperryua
+6  A: 

If you alloc an object in a function that you need to return from the function then you can't release it inside the function. The correct way to do this is to autorelease the object.

MSMutableArray *customers = [[MSMutableArray alloc] init];

// ..... do work

return [customers autorelease];

This is the approach taken by the connivence constructors like

[NSString stringWithString:@"test"];

This method will return you an autoreleased string so that you don't need to release it.

And if you don't do this then you should name your function accordingly that the caller knows that it owns the returned object and thus needed to be released. These are conventions, not a rule imposed by the compiler or run-time environment but following convention is extremely important, specially when multiple people are involved in the project.

taskinoor
I've read somewhere that autorelease is not too good to be used on iphone. but in my scenario, I really have no choice but to autorelease (this is garbage collection correct)? Is it better to return an autorelease in my GetAllCustomers method? Or to just have the repo create the array but the LoadCustomer method to release when he's done with it?
pdiddy
What you have read about autorelease is definitely not right. Go through the Apple's memory management guide. It may take one or two days to read, but will save you from lots of disaster. In this case you should autorelease in GetAllCustomers method, as the method name does not imply that the caller will own the returned object.
taskinoor
A: 

("leave a comment" is broken again today.)

And if you don't do this then you should name your function accordingly

Which function should be renamed? GetAllCustomers or LoadCustomers?

What would be the best names to use?

Sally