Re: newbie memory question
Re: newbie memory question
- Subject: Re: newbie memory question
- From: Daniel Child <email@hidden>
- Date: Mon, 15 Nov 2004 22:44:25 -1000
Thanks Harilaos.
I removed the calls to alloc and init under the init method and simply ran the code as before. I still get an initially high retain count the first time I use the variables whatTheUserTyped and theLength. Do things hold onto to variables in the background?
I have read the articles on memory you (and others) have suggested and was confused by one thing. If you have a setter method:
(void) setVar: (NSFloat) f
{
[f retain]; // The assumption is f is autoreleased, but would autorelease dump it before I use //it here?
[var release]; // This releases memory for what var previously pointed to?
[var = f]; // and now we set it to f.
}
then doesn't f keep getting retained more than it should. (This was the format suggested in the article.) And if you release var, isn't there a danger that it's retain count drops to -1 (not retained)?
In the code that I originally wrote, I tried releasing my variables after updateUI, but then when I called the countLetters again, the program crashed. If I did
not want to use accessor methods, is there a way to release things safely?
Also, presumably because of the use of convenience methods, the retain counts go to -1 and 1, respectively, after updateUI. Does that still constitute a memory leak. Here is the revised code (the init method now simply calls [super init] with no initialization of variables?
- (id)sender
{
whatUserTyped = [theStringToCount stringValue];
numLetters = [whatUserTyped length];
theLength = [NSString stringWithFormat: @"%i", numLetters];
[self updateUI];
}
- (id)sender
{
whatUserTyped = @"";
numLetters = 0;
theLength = [NSString stringWithFormat: @"%i", numLetters];
[self updateUI];
}
- (void)updateUI
{
[theStringToCount setStringValue: whatUserTyped];
[theAnswer setStringValue: theLength];
}
Assuming I do NOT want to use an accessor method, where can I safely release whatUserTyped and theLength without crashing the program?
Daniel
On Monday, November 15, 2004, at 08:28 PM, Harilaos Skiadas wrote:
Hi,
Hi Daniel,
I wrote a simple app to count the letters in a
textfield. In the code
below, I checked for retain counts. A couple of
people have suggested I
use accessor methods to avoid memory leaks, but
before I do so, I'd
like to understand where things are getting retained
so I can recognize
such problems in the future. The console results were
surprising to me.
First of all, I strongly advice you to read the
wonderful info online on memory management and
accessors. A lot of people would recommend:
http://www.stepwise.com/Articles/Technical/HoldMe.html
You can also look at:
http://www.stepwise.com/Articles/Technical/2001-03-11.01.html
And a more advanced one:
http://www.stepwise.com/Articles/Technical/2002-06-11.01.html
and of course the info at cocoadev.com
I am just going to comment on the code parts that I
think have problems, and hope that others will correct
me if I am wrong. This won't quite explain the numbers
you are getting, but hopefully will get you in the
right track.
(In the code, theStringToCount is a textfield where
the user types the
string, and theAnswer is another textfield where the
count value is
posted. All of this code is part of the MyDocument
implementation
file.)
- (id)init
{
self = [super init];
if (self)
{
whatUserTyped = [[NSString alloc] init];
theLength = [[NSString alloc] init];
Here you have just allocated memory for two objects,
which you are going to leak in countLetters, so you
probably don't want to do that.
numLetters = 0;
printf("At init, whatUserTyped retain
count is: %i\n",
[whatUserTyped
retainCount]);
printf("At init, theLength retain
count is: %i\n\n",
[theLength retainCount]);
Just a personal comment, I use NSLog instead, not
quite sure if there is a serious difference.
}
return self;
}
- (IBAction)countLetters:(id)sender
{
whatUserTyped = [theStringToCount stringValue];
numLetters = [whatUserTyped length];
What you are doing here is redirect the pointer
whatUserTyped to point to the autoreleased string that
the method stringValue returned. So, first of all,
nothing points to the object you allocated above, and
hence you are leaking it. Second, you have not
retained this string, so you certainly have not
contributed to its retain count.
theLength = [NSString stringWithFormat:
@"%i", numLetters];
Same here. You have just created an autoreleased
string, and set theLength to point to it. You haven't
retained it. (and you probably shouldn't if you don't
need the info outside the call).
printf("At countLetters, whatUserTyped retain
count is: %i\n",
[whatUserTyped
retainCount]);
printf("At countLetters, theLength retain
count is: %i\n\n",
[theLength
retainCount]);
[self updateUI];
}
Ok, enough of my comments, I'll let the experts give
more expert advice, though reading the relevant stuff
on the lots of excellent web pages devoted to it will
probably be more helpful to you in the long run. As
far as I can see, in your code you haven't retained
anything, and you have leaked exactly two things.
I hope this helps. Good luck!
Haris
__________________________________
Do you Yahoo!?
Meet the all-new My Yahoo! - Try it today!
http://my.yahoo.com
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Cocoa-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden