Understanding UIKIT_EXTERN and Macro Usage in iOS Development
This article explains the purpose, syntax, and underlying principles of UIKIT_EXTERN and related macros such as extern, static, and const in iOS, demonstrates how __attribute__ and visibility modifiers affect symbol linkage, and outlines practical scenarios and extensions for safer, more efficient code across dynamic libraries.
The author shares insights gained while optimizing macros at the compilation level in an iOS project, focusing on the UIKIT_EXTERN macro and its role in exposing symbols across dynamic libraries.
About UIKIT_EXTERN
UIKIT_EXTERN is defined to ensure global constants are available throughout the project while preventing conflicts between dynamic libraries. The macro adapts to C++ by adding extern "C" and sets the visibility attribute to "default" .
#ifdef __cplusplus
#define UIKIT_EXTERN extern "C" __attribute__((visibility ("default")))
#else
#define UIKIT_EXTERN extern __attribute__((visibility ("default")))
#endifMany frameworks, such as YYKit, adopt a similar pattern.
#ifdef __cplusplus
#define YY_EXTERN_C_BEGIN extern "C" {
#define YY_EXTERN_C_END }
#else
#define YY_EXTERN_C_BEGIN
#define YY_EXTERN_C_END
#endifUIKIT_EXTERN Code Interpretation
If compiled as C++, the macro adds the C linkage specification and visibility attribute; otherwise it only adds the visibility attribute. This ensures the symbol is visible to external code while keeping internal linkage safe.
Principle
__attribute__ is a GCC extension that allows developers to specify special compiler attributes such as visibility. Using __attribute__((visibility("default"))) makes a symbol globally visible, whereas hidden restricts it to the defining shared object.
__attribute__ ((visibility("default")))
__attribute__ ((visibility("hidden")))Visibility can be controlled with the -fvisibility flag during compilation.
Application Scenarios
Compilation optimization
Global variable declaration
Resolving symbol conflicts between different libraries
Extensions
Macro
#define __SN_PASTE__(A,B) A##B
#define SNSquare(A) __SNSQUARE_IMPL__(A,__COUNTER__)
#define __SNSQUARE_IMPL__(A,L) ({ __typeof__(A) __SN_PASTE__(__a,L) = (A); (__SN_PASTE__(__a,L)) * (__SN_PASTE__(__a,L)); })extern
// ViewController.h
int x = 24;
// BViewController.m
extern int x;
NSLog(@"x is:%d", x); // x is 24static
static int a = 3;
++a;
NSLog(@"a is %d", a); // a is 4Static variables retain their value for the program’s lifetime and exist only once in memory.
const
Const modifies the right‑hand side variable, preventing changes after initialization. In iOS, const global strings improve pre‑compilation speed.
NSString * const kTableViewCell = @"kTableViewCell";iOS Specific extern
Frameworks like UIKit and Foundation define UIKIT_EXTERN and FOUNDATION_EXTERN to provide C‑compatible extern declarations with appropriate visibility attributes.
// UIKitDefines.h
UIKIT_EXTERN const CGFloat kAnimationInterval;
// Foundation
FOUNDATION_EXTERN NSString * const kAnimationKey;Reference Documents
Macro black magic: https://onevcat.com/2014/01/black-magic-in-macro/
YYKit macro usage: https://github.com/ibireme/YYKit/blob/master/YYKit/Base/YYKitMacro.h
GCC variable attributes: https://gcc.gnu.org/onlinedocs/gcc/Variable-Attributes.html
GCC function attributes: https://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
Conclusion
Using static and const limits a variable’s scope to the current file and prevents modification, while extern declares a global variable that can be defined elsewhere; together they enable safe, clear, and efficient symbol management in iOS projects.
Sohu Tech Products
A knowledge-sharing platform for Sohu's technology products. As a leading Chinese internet brand with media, video, search, and gaming services and over 700 million users, Sohu continuously drives tech innovation and practice. We’ll share practical insights and tech news here.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.