views:

39

answers:

3

there's a static method like:

+ (id) getRoutes:(NSString *)stationName{
 NSMutableArray *routeArray = [[NSMutableArray alloc] init];
 ......
 [routeArray autorelease];
 return routeArray;
}

when i call it like following, is okay

...
@property(nonatomic, retain) NSMutableArray *routeArray;
...
@synthesize routeArray;
...
routeArray = [[Station getRoutes:self.stationName] copy];
...

if without copy, app will crashed (EXC_BAD_ACCESS) the "copy" is really necessary?

+2  A: 

Read the documentation on memory management.

NSResponder
+1  A: 

Yes, you must take the ownership of the autoreleased object to make it valid out of the current scope. For detailed information you definitely should read the docs as NSResponder suggested (memory management is probably the most must-to-know thing in obj-c).
I'd also suggest to use retain instead of copy on your array.

Edit: (thanks to gs) And as you take an ownership of the object it is your task to call release on it when you do not need this object anymore.

Vladimir
... and call `release` as soon as you don't need it anymore.
Georg
Yes, sorry. Forgot this most important thing
Vladimir
A: 

When you alloc an object, it's created with a retain count of one. Retaining an object increments the retain count, and releasing or autoreleasing it decrements the retain count. When the retain count reaches 0, the object is deallocated (not straight away, but for the purpose of this brief intro to memory management you can think of it that way.

Copying an object returns a new copy (obviously!) with a retain count of 1.

So, your getRoutes... method returns an object with a retain count of 0. If you need it to stick around, you need to retain it at once. That would be better than copying the object.

Of course, you should release the object when you're done with it, as the others have said.

Here are my memory management rules:

  • Release all objects you create using a method whose name begins "alloc" or "new" or contains "copy".
  • Release all objects you retain.
  • Do not release objects created using a +className convenience constructor. (The class creates the object and is responsible for releasing it.)
  • Do not release objects you receive (myNose = [theFace nose];) - this is your case above.
  • If you store an object you receive in an instance variable, and want to guarantee it's around for the lifetime of the object with the instance variable, ensure the object you receive is retained. (A retain property is the usual way to do this.)
  • Received objects are valid within the method they are received in (generally) and are also valid if passed back to the invoker. (This is why you can access the routeArray after calling getRoutes, but later on the object disappears, when the autorelease pool is emptied.)
Jane Sales