I have been using static const in my header files as so:
static NSString * const myString = @"foo";
But have read that this is not the 'safe' or correct way of doing this. Apparently, if I want my const strings to be accessed from another class, I should be declaring the string in my .h as:
extern NSString * const myString;
Then in my .m file:
NSString * const myString = @"foo";
Is this correct? If so, what is the reason not to declare it as static directly in my .h file? It works perfectly fine, and I can not see any 'safety' issues around this. It is a const, so therefore it can not be changed from outside and its something I intentionally need accessed outside of the class. The only other thing I can think of is that to hide the value of the string?
Your first variant
static NSString * const myString = @"foo"; // In .h file, included by multiple .m files
defines an myString
variable locally in each "translation unit" (roughly speaking: in each .m source file)
that includes the header file. All string objects have the same contents "foo",
but it may be different objects so that the value of myString
(the pointer to the string object)
may be different in each unit.
Your second variant
extern NSString * const myString; // In .h file, included by multiple .m files
NSString * const myString = @"foo"; // In one .m file only
defines a single variable myString
which is visible "globally".
Example: In one class you send a notification with myString
as user object.
In another class, this notification is received and the user object compared to myString
.
In your first variant, the comparison must be done with isEqualToString:
because
the sending and the receiving class may have different pointers (both pointing to a
NSString
object with the contents "foo"). Therefore comparing with ==
may fail.
In your second variant, there is only one myString
variable, so you can compare with ==
.
So the second variant is safer in the sense that the "shared string" is the same object in each translation unit.