Some definitions
A literal is a value that, by definition, is immutable. e.g. 10
A constant is a read-only variable or pointer. for example: const int age = 10;
A string literal is an expression of type @"" . The compiler will replace this with an instance of NSString .
String constant is a read-only pointer to an NSString . for example: NSString *const name = @"John";
Some comments on the last line:
- This is a constant pointer, not a constant object 1 .
objc_sendMsg 2 doesn't care if you qualify an object with const . If you want an immutable object, you must encode this immutability inside object 3 . - All
@"" expressions are truly immutable. They are replaced with 4 at compile time with instances of NSConstantString , which is a specialized subclass of NSString with a fixed memory layout of 5 . This also explains why NSString is the only object that can be initialized at compile time 6 .
A constant string will be const NSString* name = @"John"; , which is equivalent to NSString const* name= @"John"; . Here both syntax and programmer intentions are wrong: const <object> ignored, and the instance of NSString ( NSConstantString ) is already unchanged.
1 The const keyword is applied to what is immediately to the left of it. If nothing is left of him, this refers to what is immediately on the right.
2 This is a function that the runtime uses to send all messages to Objective-C, and therefore that you can use to change the state of an object.
3 Example: in const NSMutableArray *array = [NSMutableArray new]; [array removeAllObjects]; const NSMutableArray *array = [NSMutableArray new]; [array removeAllObjects]; const does not prevent the last statement.
4 The LLVM code that rewrites the expression, RewriteModernObjC::RewriteObjCStringLiteral in RewriteModernObjC.cpp.
5 To see the definition of NSConstantString , cmd + click it in Xcode.
6 Creating compile-time constants for other classes will be simple, but a specialized subclass will be required for the compiler. This will break compatibility with older versions of Objective-C.
sub>
Back to quote
Cocoa structures expect global string constants, not string literals, to be used for dictionary keys, notifications, and exception names and some method parameters that accept strings. You should always prefer string constants over string literals when you have a choice. Using string constants, you will enlist the help of a compiler to check your spelling and, therefore, avoid runtime errors.
It says that literals are error prone. But he does not say that they are also slower. Compare:
In the second case, I use keys with constant pointers, so instead of [a isEqualToString:b] I can do (a==b) . The implementation of isEqualToString: compares the hash and then runs the C function strcmp , so it is slower than comparing the pointers directly. Which means why constant strings are better: they compare faster and are less error prone.
If you want your constant string to be global, do the following:
// header extern NSString *const name; // implementation NSString *const name = @"john";