When I use the word extern
before a method or variable declaration, am I making it global and therefore readable/writable/usable over the entire project ?
If I use extern before a keyword, is there any chance it is still not accessible by part of my project ? For example, only by subclasses.. such as when I use "protected".
extern
is a C keyword, right? Is there an equivalent in Objective-C? I actually don't understand why they use a C keyword in an Objective-C project.
thanks
1) you're specifying its linkage. extern linkage allows you or any client to reference the symbol.
regarding global variables: if the variable is mutable and/or needs proper construction, then you should consider methods or functions for this object. the notable exception to this is NSString constants:
// MONClass.h
extern NSString* const MONClassDidCompleteRenderNotification;
// MONClass.m
NSString* const MONClassDidCompleteRenderNotification = @"MONClassDidCompleteRenderNotification";
2) there is no case where the extern keyword affects visibility (public/protected/private/package). to use the symbol (e.g. the constant or C function), simply include the header it is declared in.
somewhat confusing if you are new to the language: placing extern C declarations (constants, functions) in between @interface ... @end
will not alter its scope:
@interface MONClass : NSObject
extern const size_t MaximumThreads;
@end
has the same scope (global) and visibility (public) as:
@interface MONClass : NSObject
@end
extern const size_t MaximumThreads;
so it really makes no sense to place your class related C constants or functions in the @interface...@end
and @implementation...@end
. i recommend placing these in the same header as the interface, outside @interface/@end
and @implementation/@end
and prefixing the name with the class it is associated with, like so:
@interface MONClass : NSObject
@end
extern const size_t MONClassMaximumThreads;
// MONClass.m
const size_t MONClassMaximumThreads = 23;
and if you want that constant to be private, just declare and define it like this:
// MONClass.m
static const size_t MONClassMaximumThreads = 23;
@implementation MONClass
@end
unfortunately, there is no equally simple or common way to make this constant protected with objc.
finally, you can also use class methods if the number should vary by class:
@interface MONMammal : NSObject
+ (NSUInteger)numberOfLegs;
@end
@implementation MONDog
+ (NSUInteger)numberOfLegs { return 4; }
@end
@implementation MONHuman
+ (NSUInteger)numberOfLegs { return 2; }
@end
3) yes, among other languages. for example, if you use extern const int Something
in a c++ translation, the c++ translation will look for Something
declared as an extern C++ symbol. there is no substitution in objc; objc is a superset of C and inherits all of C's functionalities. use of extern
is well formed and you can also find it in the frameworks you use (e.g. Foundation). they use it because they need to specify linkage. objc does not offer a substitute, presumably because it did not require a replacement or extension.
to avoid this, simply use a #define
like this:
#if !defined(__cplusplus)
#define MONExternC extern
#else
#define MONExternC extern "C"
#endif
MONExternC const size_t MONClassMaximumThreads;