开发者

Objective C, Difference between NSSting with "alloc" and without "alloc"

开发者 https://www.devze.com 2023-02-16 10:13 出处:网络
NSString *s1 = @\"string1\"; // NSString *s2 = [[NSString alloc]stringWithFormat:@\"string2\"]; NSString *s2 = [[NSString alloc] initWithFormat:@\"string2\"];
 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.

0

精彩评论

暂无评论...
验证码 换一张
取 消