PDA

View Full Version : do i have to retain a member variable?




samgeribo
Jul 26, 2008, 04:08 AM
I have a class with a NSMutableArray* declared in the header file. I am not using a property for it. In the constructor I have:

-(id) initWithWidth:(int)_width Height:(int)_height Friction:(float)_friction TimeDelta:(float)_timeDelta {
if(self = [super init]) {
balls = [NSMutableArray array];
[balls retain];
width = _width;
height = _height;
friction = _friction;
timeDelta = _timeDelta;

return self;
}

My question is that if I take out the [balls retain] line my program crashes but if I leave it in it works great. Why do I have to retain it? I thought the NSMutableArray:array method automatically set the retain count to 1.



kamo
Jul 26, 2008, 09:00 AM
When you initiate an object with a convenience method (you know it's a convenience method because it has no init or copy in the name), it will be released automatically, so you need to retain it.

I would suggest using properties though.

Read the cocoa memory management guide:

http://developer.apple.com/documentation/Cocoa/Conceptual/MemoryMgmt/MemoryMgmt.html

samgeribo
Jul 26, 2008, 07:14 PM
Thanks for the quick reply!

I am still confuzzled. I know your answer is the right answer, but I'd like to have a deeper understanding. I thought the convenience methods did something like this:

+ NSMutableArray:array {
NSMutableArray* array = [[NSMutableArray alloc] init];
return [array autorelease];
}

The alloc method should set the retain count to 1. So why should I have to do a retain in my code?

On the other hand, if this method really did an autorelease without doing a retain that would seem to violate Apple's own memory management policies.

kainjow
Jul 27, 2008, 09:01 AM
Thanks for the quick reply!

I am still confuzzled. I know your answer is the right answer, but I'd like to have a deeper understanding. I thought the convenience methods did something like this:

+ NSMutableArray:array {
NSMutableArray* array = [[NSMutableArray alloc] init];
return [array autorelease];
}

The alloc method should set the retain count to 1. So why should I have to do a retain in my code?

alloc gives it a retain count of 1. autorelease doesn't change its retain count, but it puts it into the autorelease pool which gets emptied at a later point. You must retain an autoreleased object if you want to keep it around.

kamo
Jul 28, 2008, 07:15 AM
You can also create a property with the retain flag and upon assignment your object will be retained. (Make sure to release it in dealloc.)



//MyObject.h

@interface MyObject : NSObject {
NSMutableArray *balls;
}

@property (nonatomic, retain) NSMutableArray *balls;
- (void)initBalls;

@end




//MyObject.m

#import "MyObject.h"

@implementation MyObject

@synthesize balls;

- (void)initBalls {
balls = [NSMutableArray array];
}

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

@end

Taum
Jul 28, 2008, 05:15 PM
In that case you'd need to call self.balls = [NSMutableArray array]. Simply assigning the ivar won't retain the object properly (since it won't call the setBalls: method).

sujithkrishnan
Jul 29, 2008, 12:49 AM
In that case you'd need to call self.balls = [NSMutableArray array]. Simply assigning the ivar won't retain the object properly (since it won't call the setBalls: method).

Hi.

My doubt is whether such non-retaining codes will call applicationDidiRecievedMemoryWarning: method ????

My app is not crashing at a particular point.... it can happen at any point of time.... So i cant point out where its crashing... But its not crashing during the debug process, only after deployment, Once i found that it is calling the applicationDidiRecievedMemoryWarning method: But my app is taking only a maximum of 3MB during runtime....

Taum
Jul 29, 2008, 04:31 AM
If your app is "randomly" crashing with EXC_BAD_ACCESS, from my experience it is most often due to an object being dealloc'ed too early, because you didn't retain it when you should. I don't see how applicationDidReceiveMemoryWarning:, if empty, could change anything in this matter.