When I alloc
and init
two NSString
variables and compare their pointers, they are the same. Here's a snippet that shows this:
NSString *s1 = [[NSString alloc] initWithString:@"hello world"];
NSString *s2 = [[NSString alloc] initWithString:@"hello world"];
if (s1 == s2) {
NSLog(@"==");
}else {
NSLog(@"!=");
}
Why are s1
and s2
the same?
There are three things going on here:
Firstly, the two identical string literals you're passing in to
initWithString:
will have the same address to start. This is an obvious optimization for constant data.Secondly, when you nest alloc and init with strings, the runtime performs an optimization, the alloc call essentially becomes a no-op. This is done using the
NSPlaceholderString
class. This means the pointer you get back here will be coming frominitWithString:
, not from alloc.Thirdly, under the hood,
initWithString:
is callingCFStringCreateCopy
, which as you may find, has the following behavior: Since this routine is for creating immutable strings, it has an optimization. It simply callsCFRetain()
and returns the same object that was passed in.Thanks for the very interesting question. I had fun figuring it out.
@"hello world" strings are of class
NSConstantString
.if you use @"hello world" in two places, they will be referencing the very same object.From documentation.