Yanjun
Yanjun

Reputation: 95

iOS memory management about NSString

Is there any different between

NSString * str = @"123";

and

NSString * str = [[NSString alloc] initWithString:@"123"];

from compiler's aspect?

Upvotes: 0

Views: 611

Answers (6)

JeremyP
JeremyP

Reputation: 86701

Theoretically yes; in implementation detail, probably not.

In the first case, the compiler creates a constant string and assigns a pointer to it to the variable str. You do not own the string.

In the second case, the compiler creates a constant string (as before) but this time it is used by the run time as a parameter in initialising another string that you do own (because the second string was created using alloc).

That's the end of the stuff you need to know.

However, there is a lot of optimisation that goes on. Because NSStrings are immutable, you'll find that initWithString: actually just returns the parameter. Normally, it would retain the parameter before returning it to you (because you are expecting to own it) but literal strings have a special retainCount (INT_MAX I think) to stop the run time from ever trying to deallocate them. So in practice, your second line of code produces identical results to the first.

This incidentally, is why it is incorrect top say the string is autoreleased in the first case, because it isn't. It's just a constant string with a special retain count.

But you can and should safely ignore the implementation detail and just remember, you don't own the string in the first case, but you do own it in the second case.

Upvotes: 4

The main important difference about memory (your question title) is: when you do:

NSString* myString =  @"my text";

you are allocating an object of NSConstantString type.

The difference with NSString is: NSConstantString is statically allocate, while NSString is dynamically allocated.

Upvotes: 0

Neelam Verma
Neelam Verma

Reputation: 3274

Yes , first statement creates an autorelease object. Second one creates an object occupying some memory and you have to release it after using it.

Upvotes: 0

Manlio
Manlio

Reputation: 10864

Yes, in the first case you do not own the string and you are not responsible to release it.

In the second case, instead, you are calling alloc thus you become the owner of the object and you must call release on it when you have done, otherwise it will become a memory leak.

In general, if the method you use to get your object contains "new","alloc","copy" or "mutableCopy" then you are the owner of the object and you are responsible to release it.

Check the memory management rules

Upvotes: 1

yuji
yuji

Reputation: 16725

Lots of differences. The most important is that you own the second string so you're responsible for releasing it (as is the case whenever you get an object from the init family of methods).

Another is that the former creates a string literal, and if you make a new string with the same literal, they will be pointers to the same object. If you do this:

NSString * str1 = @"123"; 
NSString * str2 = [[NSString alloc] initWithString:@"123"];
NSString * str3 = @"123"; 

Then str1 == str2 is false, but str1 == str3 is true. (Of course, the string content is the same, so isEqual: will return true. Also, while this does make for faster comparison, you probably shouldn't use it because it's an implementation detail and could in theory change in the future).

Upvotes: 2

MByD
MByD

Reputation: 137442

Yes. The first is assignment of an NSString, and in the second the alloc (which means you need to release it in some way later) and initWithString: method are getting called.

Upvotes: 0

Related Questions