I'm guessing I would only use UIKIT_EXTERN if there is a chance of C++ code in my project that may use the variable.
Right. This is the primary reason. This happens because C and C++ symbols use different naming conventions.
There is a less common reason: UIKIT_EXTERN
also specifies default visibility.
Note: More generally, "symbol" -- not "variable" since extern
could also be applied to constants, functions, et cetera.
If this is the case wouldn't it just be safe to declare all your externally available constants with UIKIT_EXTERN?
Short Answer: It would be good practice (read: 'safe') to use this form, but it's usually best for your library to declare its own equivalent of UIKIT_EXTERN
.
UIKIT_EXTERN
is a UIKit declaration. Libraries should not depend on this declaration, and just define their own synonym -- and many do, but I find it is more common in C and C++ because these programs often target more platforms and a good percentage of iOS programs are not developed to support other platforms. Otherwise, Objective-C programs which do not require UIKit could depend on UIKit because of this declaration, so they would have to import UIKit (so that UIKIT_EXTERN
's declaration is visible).
Furthermore, UIKit is not available on all platforms where iOS programs could be run (i.e. it could be C, C++, or depend on Foundation and portable to OS X). So even if somebody (curiously) insisted declaring their own were a bad idea, choosing CF_EXPORT
(CoreFoundation's equivalent) would be a more portable option because it could also be used for C, C++, and on OS X. Furthermore, your library would only need to include CoreFoundation (at minimum).
If your library depends on UIKit and the framework's must be imported by your library, then it is highly unlikely that using their synonym would cause a problem for your library.
But this is a pretty big set of conditions -- it's very easy for your library to simply declare its own. In short, a well written and portable library should (almost) never use 'raw' extern
, nor should unnecessary library dependencies be a good thing (UIKit in this case).
It would be a bad design choice to use UIKIT_EXTERN
unless your library were inseparable from UIKit -- such as a collection of UIView
subclasses.
If your library just deals with Foundation types, then importing UIKit means that your library will be (unnecessarily) unusable on OS X (until that UIKit import is removed).
People who haven't much experience using C++ with C (including supersets) may not know that symbol names are different, so they may just use extern
directly. Finally, some programs were not initially designed to be used outside of C and/or Objective-C translations, so they may have simply used extern
without conditional decoration for the translation.
Finally, UIKIT_EXTERN
may not do exactly what you expect/want since it specifies:
- an extern C symbol
- which has default visibility
For library symbols visible to ObjC translations, this is perfect.