<p>I'm learning objective-C and Cocoa and have come across this statement:</p>

<blockquote>
  <p>The Cocoa frameworks expect that global string constants rather than string literals are used for dictionary keys, notification and exception names, and some method parameters that take strings.</p>
</blockquote>

<p>I've only worked in higher level languages so have never had to consider the details of strings that much. What's the difference between a string constant and string literal?</p>

[{'answer_id': 25750, 'author': 'Brad Wilson', 'author_id': 1554, 'author_profile': 'https://Stackoverflow.com/users/1554', 'pm_score': 2, 'selected': False, 'text': '<p>Let\'s use C++, since my Objective C is totally non-existent.</p>\n\n<p>If you stash a string into a constant variable:</p>\n\n<pre><code>const std::string mystring = "my string";\n</code></pre>\n\n<p>Now when you call methods, you use my_string, you\'re using a string constant:</p>\n\n<pre><code>someMethod(mystring);\n</code></pre>\n\n<p>Or, you can call those methods with the string literal directly:</p>\n\n<pre><code>someMethod("my string");\n</code></pre>\n\n<p>The reason, presumably, that they encourage you to use string constants is because Objective C doesn\'t do "interning"; that is, when you use the same string literal in several places, it\'s actually a different pointer pointing to a separate copy of the string.</p>\n\n<p>For dictionary keys, this makes a huge difference, because if I can see the two pointers are pointing to the same thing, that\'s much cheaper than having to do a whole string comparison to make sure the strings have equal value.</p>\n\n<p><strong>Edit:</strong> Mike, in C# strings are immutable, and literal strings with identical values all end pointing at the same string value. I imagine that\'s true for other languages as well that have immutable strings. In Ruby, which has mutable strings, they offer a new data-type: symbols ("foo" vs. :foo, where the former is a mutable string, and the latter is an immutable identifier often used for Hash keys).</p>\n'}, {'answer_id': 25798, 'author': 'Chris Hanson', 'author_id': 714, 'author_profile': 'https://Stackoverflow.com/users/714', 'pm_score': 7, 'selected': True, 'text': '<p>In Objective-C, the syntax <code>@"foo"</code> is an <strong>immutable</strong>, <strong>literal</strong> instance of <code>NSString</code>.  It does not make a constant string from a string literal as Mike assume.</p>\n\n<p>Objective-C compilers typically <em>do</em> intern literal strings within compilation units — that is, they coalesce multiple uses of the same literal string — and it\'s possible for the linker to do additional interning across the compilation units that are directly linked into a single binary.  (Since Cocoa distinguishes between mutable and immutable strings, and literal strings are always also immutable, this can be straightforward and safe.)</p>\n\n<p><strong>Constant</strong> strings on the other hand are typically declared and defined using syntax like this:</p>\n\n<pre><code>// MyExample.h - declaration, other code references this\nextern NSString * const MyExampleNotification;\n\n// MyExample.m - definition, compiled for other code to reference\nNSString * const MyExampleNotification = @"MyExampleNotification";\n</code></pre>\n\n<p>The point of the syntactic exercise here is that you can make <em>uses of</em> the string efficient by ensuring that there\'s only one instance of that string in use <em>even across multiple frameworks</em> (shared libraries) in the same address space.  (The placement of the <code>const</code> keyword matters; it guarantees that the pointer itself is guaranteed to be constant.)</p>\n\n<p>While burning memory isn\'t as big a deal as it may have been in the days of 25MHz 68030 workstations with 8MB of RAM, comparing strings for equality can take time.  Ensuring that most of the time strings that are equal will also be pointer-equal helps.</p>\n\n<p>Say, for example, you want to subscribe to notifications from an object by name.  If you use non-constant strings for the names, the <code>NSNotificationCenter</code> posting the notification could wind up doing a lot of byte-by-byte string comparisons when determining who is interested in it.  If most of these comparisons are short-circuited because the strings being compared have the same pointer, that can be a big win.</p>\n'}, {'answer_id': 12327650, 'author': 'Jano', 'author_id': 412916, 'author_profile': 'https://Stackoverflow.com/users/412916', 'pm_score': 4, 'selected': False, 'text': '<h2>Some definitions</h2>\n\n<p>A <strong>literal</strong> is a value, which is immutable by definition. eg: <code>10</code><br>\nA <strong>constant</strong> is a read-only variable or pointer. eg: <code>const int age = 10;</code><br>\nA <strong>string literal</strong> is a expression like <code>@""</code>. The compiler will replace this with an instance of <code>NSString</code>.<br>\nA <strong>string constant</strong> is a read-only pointer to <code>NSString</code>. eg: <code>NSString *const name = @"John";</code></p>\n\n<p>Some comments on the last line:</p>\n\n<ul>\n<li>That\'s a constant pointer, not a constant object<sup>1</sup>. <code>objc_sendMsg</code><sup>2</sup> doesn\'t care if you qualify the object with <code>const</code>. If you want an immutable object, you have to code that immutability inside the object<sup>3</sup>.  </li>\n<li>All <code>@""</code> expressions are indeed immutable. They are replaced<sup>4</sup> at compile time with instances of <code>NSConstantString</code>, which is a specialized subclass of <code>NSString</code> with a fixed memory layout<sup>5</sup>. This also explains why <code>NSString</code> is the only object that can be initialized at compile time<sup>6</sup>.</li>\n</ul>\n\n<p>A <strong>constant string</strong> would be <code>const NSString* name = @"John";</code> which is equivalent to <code>NSString const* name= @"John";</code>. Here, both syntax and programmer intention are wrong: <code>const &lt;object&gt;</code> is ignored, and the <code>NSString</code> instance (<code>NSConstantString</code>) was already immutable.</p>\n\n<p><sub><sup>1</sup> The keyword <code>const</code> applies applies to whatever is immediately to its left. If there is nothing to its left, it applies to whatever is immediately to its right.</sub> </p>\n\n<p><sub><sup>2</sup> This is the function that the runtime uses to send all messages in Objective-C, and therefore what you can use to change the state of an object. </p>\n\n<p><sub><sup>3</sup> Example: in <code>const NSMutableArray *array = [NSMutableArray new]; [array removeAllObjects];</code> const doesn\'t prevent the last statement.</sub></p>\n\n<p><sub><sup>4</sup> The LLVM code that rewrites the expression is <code>RewriteModernObjC::RewriteObjCStringLiteral</code> in RewriteModernObjC.cpp.</sub>  </p>\n\n<p><sub><sup>5</sup> To see the <code>NSConstantString</code> definition, cmd+click it in Xcode.</sub> </p>\n\n<p><sub><sup>6</sup> Creating compile time constants for other classes would be easy but it would require the compiler to use a specialized subclass. This would break compatibility with older Objective-C versions.</sub>   </p>\n\n<p></sub></p>\n\n<hr>\n\n<h2>Back to your quote</h2>\n\n<blockquote>\n  <p>The Cocoa frameworks expect that global string constants rather than\n  string literals are used for dictionary keys, notification and\n  exception names, and some method parameters that take strings. You\n  should always prefer string constants over string literals when you\n  have a choice. By using string constants, you enlist the help of the\n  compiler to check your spelling and thus avoid runtime errors.</p>\n</blockquote>\n\n<p>It says that literals are error prone. But it doesn\'t say that they are also slower. Compare: </p>\n\n<pre><code>// string literal\n[dic objectForKey:@"a"];\n\n// string constant\nNSString *const a = @"a";\n[dic objectForKey:a];\n</code></pre>\n\n<p>In the second case I\'m using keys with const pointers, so instead <code>[a isEqualToString:b]</code>, I can do <code>(a==b)</code>. The implementation of <code>isEqualToString:</code> compares the hash and then runs the C function <code>strcmp</code>, so it is slower than comparing the pointers directly. Which is <strong>why constant strings are better:</strong> they are faster to compare and less prone to errors. </p>\n\n<p>If you also want your constant string to be global, do it like this:</p>\n\n<pre><code>// header\nextern NSString *const name;\n// implementation\nNSString *const name = @"john";\n</code></pre>\n'}]
['https://Stackoverflow.com/questions/25746', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/2799/']