问题
This is probably a question that is more about object alloc/retain/release, but I'll use NSString as an example. I'm aware that I can do:
NSString* myString = [[NSString alloc] initWithString:@"Test"];
to essentially allocate and initialize a string referenced by my variable myString which I should later call [myString release] upon. However, if after I do this, I set it to some other string such as:
myString = someOtherString;
does that essentially create a memory leak because I've reassigned my pointer to another object and lost all reference to the original one I allocated?
If I simply want to personally allocate and release a string and then change its value at various times, should I be using a different syntax other than '=' or is that overloaded to properly change the contents of the object that is originally represented by myString when I use =.
回答1:
Yes, in your example you are leaking the memory.
NSString* myString = [[NSString alloc] initWithString:@"Test"];
myString = someOtherString;
You this should be done like so:
NSString* myString = [[NSString alloc] initWithString:@"Test"];
[myString release];
myString = someOtherString;
The best way I have heard the whole retain/release thing described is imagine you are walking a dog for someone. Your "object" is a dog and "retain" puts a leash on the dog and "release" takes a leash off. You can have as many leashes on the dog as you want but you want to keep at least one leash on the dog so he doesn't run free (leak) and you want to take all the leashes off the dog once you get it back to the owner (you want to get rid of the object). In your example, you can think of it as letting go of the leash on the dog mid-walk and picking up the leash of a different dog.
回答2:
If you relinquished ownership properly before assigning another pointer value to it, there is no leak:
NSString *a = [[NSString alloc] init];
// ...
[a release]; // relinquish ownership
a = someOtherString; // fine, we don't own the previous instance anymore
The moment you relinquish ownership of an object by calling release
, you should consider it effectively deallocated - this might have been the last reference to it. That the pointer still has the same value is just a side-effect of how Objective-C class types are implemented and used.
Depending on memory constraints and what your code does, you could also use autorelease
d instances:
NSString *a = [NSString stringWithString:@"moo"];
a = someOtherString; // fine, a will be released later by the nearest autorelease pool
Note that if the reference isn't a local variable but an ivar, you'll probably want to use declared properties instead.
回答3:
You could do the following:
NSString *myString = [NSString stringWithString:@"Test"];
The returned string is autoreleased so you don't have to release it. You also don't "own" it. If that's an issue do as other's have suggested and send a release
message to myString
before you reassign it's value.
来源:https://stackoverflow.com/questions/3312485/obj-c-nsstring-and-alloc-retain-release