In my iOS/Objective C projects, I often have a constants.h file with my API keys and such. Until today, I've been declaring my constants as static
const
like so:
static NSString * const kAPIKey = @"wembvkejrvb43789gvbiu2bvfake";
This works fine, but with the unfortunate downside that I can only create constants for primitives and NSString literals, essentially. Other objects, such as UIColor objects, cannot be stored in this constant as they cannot be initialized with a static literal syntax (my understanding, citation required).
After reading some C++ docs, I understand a few things:
static
is unnecessary, as const
are implicitly static.NSString * const x
is actually declaring a constant and immutable value in x. I cannot change the value, but may be able to change what x points to.Are these conclusions correct?
How does an extern const
differ? I assume they are externally linked (thus the extern keyword). Are they defined at run time? Can I create some sort of dynamic extern const
that can be set with a value returned by a class method?
For example, I would like to create a globally-scoped constant that contains a UIColor value. I would like to construct this color value using the [UIColor colorWithRed:green:blue:alpha:]
class method. This clearly doesn't work with the internally linked constants I've been using (I'm assuming because it happens at compile-time) - but is it possible using an external constant, possibly set up in the +initialize
method?
Any elaboration on the details of this behavior would be immensely helpful.
On your specific programming question, how to create a compile-time defined color object: you can't, because, apart from the handful for which the language supplies literal syntax, objects are created at runtime.
But you can still do it elegantly at runtime, without any addition to global scope, the same way the sdk does...
@interface UIColor (RainbowAddition)
+ (UIColor *)chartruseColor;
@end
@implementation UIColor (RainbowAddition)
+ (UIColor *)chartruseColor {
// bonus: this is really chartruse... according to the internet
return [self colorWithRed:0.5 green:1.0 blue:0.0 alpha:1.0];
}
@end
http://cloford.com/resources/colours/500col.htm
The static is unnecessary, as const are implicitly static.
No, that's not true.
static
when used at file scope (i.e. outside any method or function) means that the variable is visible only within that file.
extern
means that the variable is defined in some other file.
const
means that the variable cannot be modified.
Consider strings. Often, you'll have an implementation file (name ends in .m) that defines some constant string pointer:
NSString *const SomeString = @"some string";
You might want to use that same constant from other files. If so, you could add a declaration to the header (name ends in .h) file that explains to the compiler that the variable is defined elsewhere:
extern NSString *const SomeString;
and that would let you use SomeString
in any file that imports the header file. On the other hand, you might decide that you definitely do not want the constant used outside the implementation file. In that case, you could declare it static
(in the implementation file again):
static NSString *const SomeString = @"some string";
and that would prevent its use from outside the file.
Calling
NSString * const x
is actually declaring a constant and immutable value in x. I cannot change the value, but may be able to change what x points to.
Right, it declares the pointer x
to be constant -- you can't change it. You also can't change the value that it points to if it's actually a NSString
because an instance NSString
isn't mutable.
This const has internal linkage, meaning the the value is defined right away (presumable at compile time).
I'll take the 5th on that -- I'm not sure exactly how the compiler deals with constant strings. I think it's safe to use that as a mental model, though; the string will in any case be defined before your code ever gets to use it.
Objective-C is a pure extension of C, C++ is not.
At global scope:
const
is equivalent to extern const
(external linkage);const
is equivalent to static const
(internal linkage).Both in C (and Objective-C) and C++, to create a global-scoped const
you can define it, just one time, in one source file like extern const TYPE identifier = VALUE;
and declare it (typically in an header file) like: extern const TYPE identifier;
(read it: I defined this const elsewhere at global linkage level).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With