Reputation: 11314
I was going through the memory management concepts. I created one string1
and assign that string1
into another string2
, now I release this string1
.
Here string2
retain count is 1 but on NSLog
statement it gives EXC Bad access.
When I am assigning the string
NSString * string1 = [[NSString alloc]initWithFormat:@"hello"];
string2 = string1;
NSLog(@"string1 memory address = %p, string2 memory address = %p", &string1, &string2);
[string1 release];
NSLog(@"[string2 retainCount] = %lu", (unsigned long)[string2 retainCount]);
NSLog(@"string2 = %@", string2); // here app is crashing
Does it means that string2 has an autorelease message also with it because if I do string2 = [string1 copy];
instead of string2 = string1;
it doesn't crash.
So I wanted to ask whether the crash is because it has autorelease message of string2
and how it is relating with string2
release command.
Please advice!
Upvotes: 0
Views: 47
Reputation: 4278
Assignment doesn't change object's retain count if you use manual memory management in Objective-C. And you for sure use it, otherwise, you can't invoke release
method in your code.
So, your code does the following. It creates NSString
object with retain count = 1, and assigns it to string1
pointer. After that, you assigns string1
to string2
. Now you have 2 pointers to the same object, and retain count of this object is still 1. Then you release object, it deallocated immediately. And after that you experiencing crash:
NSString * string1 = [[NSString alloc]initWithFormat:@"hello"]; // string retain count is 1
string2 = string1; // 2 pointers to same string, retain count is still 1
[string1 release]; // string is deallocated when retain count drops to 0
NSLog(@"string2 = %@", string2); // here app is crashing
To fix that, you can use retain
when you do an assignment.
NSString * string1 = [[NSString alloc]initWithFormat:@"hello"]; // string retain count is 1
string2 = [string1 retain]; // 2 pointers to same string, retain count is 2
[string1 release]; // string retain count back to 1
NSLog(@"string2 = %@", string2); // no crash
Also, you can use copy
. Note that for NSString
copy doesn't actually copies an object, it simply invokes retain
. There is no need to perform actual copying, because NSString
is immutable and can't be changed. If we will use NSMutableString
, things will change:
NSMutableString * string1 = [[NSMutableString alloc]initWithFormat:@"hello"]; // string retain count is 1
NSMutableString * string2 = [string1 copy]; // 2 separate strings, both have retain count 1
[string1 release]; // string1 is deallocated
NSLog(@"string2 = %@", string2); // no crash, string2 retain count is 1
Alternatively, you can use ARC. It will insert corresponding retain/release calls at compile time. Code then will look like:
NSString * string1 = [[NSString alloc]initWithFormat:@"hello"];
string2 = string1;
string1 = nil;
NSLog(@"string2 = %@", string2); // no crash
I suggest to understand manual memory management first, and after that migrate to ARC.
Upvotes: 1