Fran Sevillano
Fran Sevillano

Reputation: 8163

NSString property making a shallow copy

I am having some trouble understanding what is going on with these two string properties declared in separate classes:

@property (nonatomic, copy) NSString *userPhone;

and

@property (nonatomic, copy) NSString *userLogin;

Somewhere in the code I go and do the following:

user.userPhone = self.userLogin;

What I would expect is that userLogin gets copied into a new object and assigned to userPhone. However, I found out that they both share a reference to the same object! So when userLogin get released, so does userPhone, breaking my poor app.

I know that I am missing something about memory management here, but I don't understand why copy does not work in this case.

Anyone knows?

Thanks a lot

Upvotes: 2

Views: 945

Answers (2)

Kaiser
Kaiser

Reputation: 688

You may be double releasing the original. If i remember the copy property will actually just retain an immutable copy (i.e NSString) and only do a hard copy if it is mutable (NSMutableString). Its possible the original string is autoreleased and you give it a hard release, accounting for two decrements. Edit:

After reading other posts i have changed mine to reflect.

Upvotes: -1

albertamg
albertamg

Reputation: 28572

NSString objects are immutable, meaning that their contents can not change once they have been created. To exploit this, the copy method does not create a new string. Instead, it retains the original string*. This is an internal optimization, from your point of view standard memory management rules apply. If you have problems with the string being deallocated before you expect, you must be over-releasing it somewhere else.

stringWithString: is also internally optimized in the same manner. If you pass an immutable string as the argument, it will not create a new one*. If you execute the following code, you will see that string1 and string2 addresses are the same.

NSString *string1 = @"Test";
NSString *string2 = [NSString stringWithString:string1];
NSLog(@"%p, %p",string1, string2);

(*) These are implementation details that are subject to change at any time.

Upvotes: 7

Related Questions