Objective C, Difference between NSSting with "alloc" and without "alloc"
NSString *s1 = @"string1";
// NSString *s2 = [[NSString alloc]stringWithFormat:@"string2"];
NSString *s2 = [[NSString alloc] initWithFormat:@"string2"];
I know this is pretty basic concept but I am not 100% clear with this.
Firs开发者_StackOverflow社区t one doesn't allocate a memory address and send one allocates a memory address... Also second one increases the reference count of the variable but not the first one... Even though I understand the concept but don't know the situation when I should use the first one or the second one..
When should I use the first one ? also when should use for the second one?
Thanks in advance..
Carl is is right, but there is some subtlety to keep in mind. Consider this:
NSString *s1 = @"string1";
NSString *s2 = [[NSString alloc] initWithString:@"string1"];
NSString *s3 = [NSString stringWithString:@"string1"];
NSString *s4 = [NSString stringWithFormat:@"string1"];
NSLog(@"ptrs %p %p %p %p", s1, s2, s3, s4);
The output is:
ptrs 0x1000010c0 0x1000010c0 0x1000010c0 0x100108da0
That's right; s1
, s2
, and s3
are all pointing to the same string instance while s4
ends up being a new instance. This is because NSString
detects when a string is being initialized from a constant string and, when perfectly valid to do so, returns the constant string instead of bothering to allocate a new chunk of memory to hold the same thing. The stringWithFormat:
case is not so optimized likely because all the potential format string processing makes such an optimization both moot and, likely, unnatural to the implementation.
In other words, do not assume that two strings are the same or different merely by code inspection or by pointer comparison. Use isEqual:
or, better yet, isEqualToString:
.
You should never use the second one - +stringWithFormat:
is a class method. Including your first example, you have basically 3 choices:
NSString *s1 = @"string1";
NSString *s2 = [[NSString alloc] initWithString:@"string2"];
NSString *s3 = [NSString stringWithFormat:@"string3"];
s1
in this case is a pointer to a constant string. s2
and s3
both point to new strings that you've created, but s2
has been retained for you, and s3
has been autoreleased. If you just need a temporary object, the autoreleased object s3
or the constant object s1
are good choices. If you need to keep the string around, you should use s2
(actually now that I think about it s1
will work in this case too - it's not really idiomatic, though).
You can make s1
or s3
equivalent to s2
by sending them a retain
message. You could also turn s2
into an equivalent object by sending it an autorelease
message.
A string literal like @"string1"
(or the @"string2"
on the second line) is, as you've noted, not an allocation. The string is actually stored as a constant in your executable's data section, just like any constant you've declared. Strings created this way don't really have a reference count; you can send -retain
and -release
messages to them and nothing will happen.
Your second line is ill-formed; +stringWithFormat:
is actually a class method, and it doesn't really make sense to use +stringWithFormat:
without having any format parameters. In general, just use the string literal form if you don't have a specific reason to use another form. There's no need to allocate a new object if there's already the constant one floating around your application.
Don't use any ...WithFormat:
method if you're just going to pass it a constant string. No need to parse the format string for the trivial case.
精彩评论