I have a class named:
Data
and it have variables:
NSString *datetime, UIImage *myPicture;
Class doesn't have any alloc or release methods for these variables.
In another class I put Data- class objects to the nsMutableArray *dataArray with addObject- method.
//Local variables
NSString *datetime;
UIImage *myPicture;
Data *myData = [[Data alloc] init];//Does nothing else than retain class
The question is, do I need use retain with datetime and myPicture variables(like myData.myPicture = [myPicture retain];) when I put data to myData.datetime and myData.myPicture or can nsMutableArray addObject- method retain myData.datetime and myData.myPicture variables when it retain myData- class?
Ask yourself at all times "who is retaining this object?" If no one is retaining an object it'll get destroyed. You're releasing too much - much too much. In this snippet the only thing you should release are formatter and myData. For now let's look at datetime instead.
Code:
//stringFromDate returns autorelease string
datetime = [formatter stringFromDate:date];
myData.datetime = datetime;
[dataArray addObject: myData];
//release the string, destroying it - it'll now crash later
//when the autorelease pool is drained or you try to access the object
[myData.datetime release];
//release the string again; will probably crash right now
[datetime release];
[myData release];
*IF* the property datetime is declared as (nonatomic,retain) -- which is what you want for objects -- then this is the correct way to do what you're doing:
Code:
//stringFromDate returns autorelease string
datetime = [formatter stringFromDate:date];
myData.datetime = datetime;
[dataArray addObject: myData];
//no need to release anything - datetime is in the autorelease pool,
//and myData is the only thing retaining it. If you had alloc/init'ed
//datetime (not gotten an autorelease string) then you would
//release it here.
//release mydata; it's being retained by the array,
//so it doesn't get destroyed
[myData release];
You should write a dealloc method for your Data class so that it can release its properties when the object gets destroyed. It'll look something like this:
Is there a way to list the variables that still have a reference/retain count when you exit your app?
Yes, the "leaks" instrument will show an list (updated every few seconds) of the objects that you've "leaked" - that is, any object that is still retained but which you have no pointers to. You can also drill down to see where that object was created; then you can look at your code to figure out what's wrong with its life cycle.
Ask yourself at all times "who is retaining this object?" If no one is retaining an object it'll get destroyed. You're releasing too much - much too much. In this snippet the only thing you should release are formatter and myData. For now let's look at datetime instead.
Code:
//stringFromDate returns autorelease string
datetime = [formatter stringFromDate:date];
myData.datetime = datetime;
[dataArray addObject: myData];
//release the string, destroying it - it'll now crash later
//when the autorelease pool is drained or you try to access the object
[myData.datetime release];
//release the string again; will probably crash right now
[datetime release];
[myData release];
*IF* the property datetime is declared as (nonatomic,retain) -- which is what you want for objects -- then this is the correct way to do what you're doing:
Code:
//stringFromDate returns autorelease string
datetime = [formatter stringFromDate:date];
myData.datetime = datetime;
[dataArray addObject: myData];
//no need to release anything - datetime is in the autorelease pool,
//and myData is the only thing retaining it. If you had alloc/init'ed
//datetime (not gotten an autorelease string) then you would
//release it here.
//release mydata; it's being retained by the array,
//so it doesn't get destroyed
[myData release];
You should write a dealloc method for your Data class so that it can release its properties when the object gets destroyed. It'll look something like this: