I was trying to answer another question about the == operator and I created this code:
NSString *aString = @"Hello";
NSString *bString = aString;
NSString *cString = @"Hello";
if (aString == bString)
NSLog(@"CHECK 1");
if (bString == cString)
NSLog(@"CHECK 2");
if ([aString isEqual:bString])
NSLog(@"CHECK 3");
if ([aString isEqual:cString])
NSLog(@"CHECK 4");
NSLog(@"%i", aString);
NSLog(@"%i", bString);
NSLog(@"%i", cString);
But was surprised at the results:
Equal[6599:10b] CHECK 1
Equal[6599:10b] CHECK 2
Equal[6599:10b] CHECK 3
Equal[6599:10b] CHECK 4
Equal[6599:10b] 8240
Equal[6599:10b] 8240
Equal[6599:10b] 8240
Is there some compiler trickery going on here?
There is clearly string uniquing going on, at least within a single compilation unit. I recommend you take a brief tour through
man gccduring which you visit all uses of “string”. You’ll find a few options that are directly relevant to literalNSStrings and their toll-free-bridged counterparts,CFStrings:-fconstant-string-class=class-name sets the name of the class used to instantiate@"..."literals. It defaults toNSConstantStringunless you’re using the GNU runtime. (If you don’t know if you are, you aren’t.)-fconstant-cfstringsenables use of a builtin to createCFStrings when you writeCFSTR(...).You can disable uniquing for C string literals using
-fwritable-strings, though this option is deprecated. I couldn’t come up with a combination of options that would stop the uniquing ofNSStringliterals in an Objective-C file. (Anyone want to speak to Pascal string literals?)You see
-fconstant-cfstringscoming into play inCFString.h‘s definition of theCFSTR()macro used to createCFStringliterals:If you look at the implementation of the non-builtin
__CFStringMakeConstantString()inCFString.c, you’ll see that the function does indeed perform uniquing using a very largeCFMutableDictionary:See also responses to the question, “What’s the difference between a string constant and a string literal?”