 |
 |
stringByAppendingString and memory
|
 |
|
 |
|
Fresh-Faced Recruit
Join Date: Dec 2008
Status:
Offline
|
|
Please consider this fragment when inside an autorelease pool
NSString *msg = @"Here it is";
msg = [msg stringByAppendingString:@", and there it goes"];
My question is what happens to the first string. I know that a new string has been created and I am wondering if both strings...
'Here it is' and the new string 'Here it is, and there it goes' will both be released when the autorelease pool releases, or is the first string that msg pointed to now lost, (as msg no longer points to it), and thus a memory leak?
I assume that the autorelease pool keeps tabs on both strings, yet I see so many examples that look more like the fragement below that I have some concerns about this.
I see some people doing it as shown above and others doing the following:
NSString *msg = @"Here it is";
NSString *newmsg;
newmsg = [msg stringByAppendingString:@", and there it goes"];
Thanks in advance for any help.
|
|
|
| |
|
|
|
 |
|
 |
|
Clinically Insane
Join Date: Oct 2001
Location: San Diego, CA, USA
Status:
Offline
|
|
An autorelease pool doesn't "keep tabs" on anything. It sends a release message to each of its objects once for every time the object has received an autorelease message. The string is not autoreleased just because you reassigned a variable that pointed to it. In this case, though, it makes no difference. Constant strings (like @"Here it is") always live for the whole lifetime of your program.
I find it more useful to think about ownership (as explained in the memory management guide) than to always wonder whether an object has been autoreleased. Have I taken ownership of an object? Then I need to release that ownership. In this case, you haven't taken ownership of anything. If it had been a string you did own, you would need to send it release or autorelease.
|
|
Chuck
___
"Instead of either 'multi-talented' or 'multitalented' use 'bisexual'."
|
| |
|
|
|
 |
|
 |
|
Fresh-Faced Recruit
Join Date: Dec 2008
Status:
Offline
|
|
So in the following case where a class has a method like so:
-(NSString*)myMethod
{
NSString *msg = @"Here it is";
NSString *newmsg;
newmsg = [msg stringByAppendingString:@", and there it goes"];
return (newmsg);
}
If my method was called 3 times during the program would msg be hanging around in memory 3 times? I know this is a real newbe question, but I thought the method going out of scope would free up the variables it created, forcing me to retain the return value (newmsg)
Thanks
|
|
|
| |
|
|
|
 |
|
 |
|
Posting Junkie
Join Date: Dec 2000
Status:
Offline
|
|
Nope, it'll be the same instance of msg each time. Cocoa keeps constant strings around in memory, so the next time you use the same constant string, you'll get the same instance. I don't think constant strings go away even if you explicitly release them - they're around for the long haul, so I wouldn't worry too much about the memory management there.
|
|
|
| |
|
|
|
 |
|
 |
|
Fresh-Faced Recruit
Join Date: Dec 2008
Status:
Offline
|
|
Thanks, I think I get it now.
msg is a constant string so it lives for the life of the program.
newmsg was created by an NSString method other than new, alloc, or copy so it is automatically added to the autorelease pool and it will get released when the current pool is released.
For example, lets say I have a class with 2 methods as follows:
-(NSString)message;
{
NSString *msg = @"Here it is";
NSString *newmsg;
newmsg = [msg stringByAppendingString:@", and there it goes"];
return (newmsg);
}
-(void)loadIt  NSString*)str
{
// stupid, worthless code to create a lost pointer
NSString *msg = [[NSString alloc]init];
msg = str;
}
Stupid code, I know but if I am getting this correct:
From the message method:
msg is a constant string and will live for the life of the program.
newmsg is automatically added to the autorelease pool and will be deallocated when the current pool releases.
From the loadIt method:
msg was created by me and is not automatically added to the autorelease pool.
It points to str, and as long as str is not released msg will point to a valid string, but as soon as I exit the method, I loose sight of msg,(scope?), and I have created a pointer and then lost it.
If str is released, msg will point to 'something', be inaccessable, and is a memory leak.
Is this correct?
Say I did the following:
-(NSString*)loadIt  NSString*)str
{
NSString *msg = [[NSString alloc]init];
msg = str;
return (msg);
}
In this case, if str is released by something else, will msg still be a valid pointer, (have I put a leash on str when I assigned msg = str), or will it be waiting to blow up in my face when I try to use it?
Thanks,
Mike
|
|
|
| |
|
|
|
 |
|
 |
|
Clinically Insane
Join Date: Oct 2001
Location: San Diego, CA, USA
Status:
Offline
|
|
Originally Posted by toadkiller
For example, lets say I have a class with 2 methods as follows:
-(NSString)message;
{
NSString *msg = @"Here it is";
NSString *newmsg;
newmsg = [msg stringByAppendingString:@", and there it goes"];
return (newmsg);
}
-(void)loadIt:(NSString*)str
{
// stupid, worthless code to create a lost pointer
NSString *msg = [[NSString alloc]init];
msg = str;
}
Stupid code, I know but if I am getting this correct:
From the message method:
msg is a constant string and will live for the life of the program.
newmsg is automatically added to the autorelease pool and will be deallocated when the current pool releases.
This is correct.
Originally Posted by toadkiller
From the loadIt method:
msg was created by me and is not automatically added to the autorelease pool.
It points to str, and as long as str is not released msg will point to a valid string, but as soon as I exit the method, I loose sight of msg,(scope?), and I have created a pointer and then lost it.
If str is released, msg will point to 'something', be inaccessable, and is a memory leak.
Is this correct?
No, you leak memory as soon as you write msg=str. At that moment, you're taking the object you got from [[NSString alloc] init] and tossing it away, then telling msg to point to the string that was passed into the method. I'll color the objects so you can watch the flow:
-(NSString*)loadIt:(NSString*)str //the object str points to is marked in red
{
NSString *msg = [[NSString alloc]init]; //Here you get a new object marked in blue
msg = str; //Here you're assigning the red variable to msg
return (msg); //What happened to the blue object? It leaked!
}
Originally Posted by toadkiller
In this case, if str is released by something else, will msg still be a valid pointer, (have I put a leash on str when I assigned msg = str), or will it be waiting to blow up in my face when I try to use it?
I don't know what you mean "put a leash on str." There's no concept of a "leash" in Objective-C. Besides that, the variable msg only exists in that method. If str is later released by something else, it doesn't make a difference to that method, because it's already finished executing.
If you're asking whether assigning an object to a variable retains the object, the answer is no. You have to retain it yourself.
(Last edited by Chuckit; Dec 12, 2008 at 06:08 PM.
)
|
|
Chuck
___
"Instead of either 'multi-talented' or 'multitalented' use 'bisexual'."
|
| |
|
|
|
 |
|
 |
|
Fresh-Faced Recruit
Join Date: Dec 2008
Status:
Offline
|
|
Thanks for the anwsers.
Yes, by leash I was refering retaining it. I was told to think of retaining an object as putting a leash on a dog. Five people can put leashes on a dog, (each retaining it, or increasing its reference count), and the dog only gets away when everyone has dropped his leash.
I appreciate all the help.
Mike
|
|
|
| |
|
|
|
 |
 |
|
 |
|
|
|
|
|

|
|
 |
Forum Rules
|
 |
 |
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
|
HTML code is Off
|
|
|
|
|
|
 |
 |
 |
 |
|
 |
|