I want to compare the following simple assignments:
...
@property(nonatomic,retain) UITextField *textField;
...
self.textField.text = @\"some string\";
self
I don't think it matters if you use the first or the second for strings. I usually use the second one however.
In the case of the second and third, if you have another variable you would like to include in your string then you use the stringWithFormat one. Otherwise, use stringWithString.
int number = 5;
NSString *str = [NSString stringWithFormat:@"Number is: %i", number];
// Str is "Number is: 5"
Situation where you would use stringWithString:
NSString *myName = [NSString stringWithString:@"FN LN"];
// myName is "FN LN"
You would use the latter when you have no other variables to include in the string.
Also, this question has been answered countless times elsewhere.
Always try to do what feels natural. If you're assigning a constant string then do that, i.e. the first option. @"..."
strings are very efficient constants that do not need to be memory managed, so use them if it makes sense.
NSLog(@"%p", @"XX");
NSLog(@"%p", @"XX");
NSLog(@"%p", @"XX");
Results in:
0xa2424
0xa2424
0xa2424
i.e. They are all the same object in memory.
NSLog(@"%p", [NSString stringWithString:@"XX"]);
NSLog(@"%p", @"XX");
NSLog(@"%p", [NSString stringWithString:@"XX"]);
Also results in:
0xa2424
0xa2424
0xa2424
As you can see from this there is no difference between the two objects, thus using -stringWithString:
is just an extra message to send. Having said that, the overhead is usually not big enough to make a difference, so it shouldn't be a big deal either way. Personally I'd go with method one as there is no benefit of using method two, it's just extra code.
However,
NSLog(@"%p", [NSString stringWithFormat:@"XX"]);
NSLog(@"%p", [NSString stringWithFormat:@"XX"]);
NSLog(@"%p", [NSString stringWithFormat:@"XX"]);
Results in:
0x7f86730
0xf8479b0
0x8a4cdb0
As you can see, a new string is created each time as the sting you provide is just a format string that is used to process the following substitution variables, as you have none avoid stringWithFormat:
unless you need it.
(Obviously all addresses are examples...)
For doing this kind of assignment, why shouldn't I always use the first one?
For that kind of assignment you would always use the first one, and never the last two.
why should I use stringWithString: at all if not?
Your intuition is correct. In most cases -stringWithString:
is of dubious value. It's primarily meant for use with NSMutableString
, which is a subclass of NSString
.
For example:
NSMutableString* myString = [NSMutableString stringWithString:@"Foo"];
[myString appendString:@"Bar"];
You can also use it if you want to convert an NSMutableString to NSString, or otherwise ensure that you're dealing with an NSString instance. For example:
- (void):setMyString:(NSString*)newString
{
[_myString release];
_myString = [[NSString stringWithString:newString] retain];
}
That's one way to ensure that the _myString
ivar is pointing to an NSString instance and not an NSMutableString instance. And the newString
instance is only copied if necessary.
However, most developers would just use _myString = [newString copy];
in that case.
For doing this kind of assignment, why shouldn't I always use the first one?
You should always use the first one in the situation you describe. The second and third cases potentially copy the constant string, but the text
property of UITextField is specified as copying the provided string anyway. There's no sense in making a copy of a constant string just so UITextField's -setText:
can copy that copy.
Comparing the last two, is there any difference for the compile- and/or runtime of these two? And why should I use stringWithString: at all if not?
My understanding is that -stringWithFormat:
will always create a new string, while -stringWithString:
might not (probably doesn't) for a constant string. hypercrypt's results above are pretty telling in this respect; if you wanted to explore that more, you might try the same test with a mutable string.