Mobile Development 12 min read

Unlocking UIKIT_EXTERN: How Macros Shape iOS Compilation and Symbol Visibility

This article explores the purpose and implementation of UIKIT_EXTERN and related macros in iOS, explaining how they manage global constants, control symbol visibility across dynamic libraries, and provide practical examples of extern, static, and const usage for compilation optimization and conflict resolution.

Sohu Smart Platform Tech Team
Sohu Smart Platform Tech Team
Sohu Smart Platform Tech Team
Unlocking UIKIT_EXTERN: How Macros Shape iOS Compilation and Symbol Visibility

Small Macro, Big World

Preface: describing the hardest technology in the simplest language.

本人是作者在对项目中的宏进行编译层面优化时有感而发的文章,如果有那些论述模糊或者不准确,请联系 [email protected]

Table of Contents

About UIKIT_EXTERN

UIKIT_EXTERN Code Walkthrough

Principle

Application Scenarios

Extensions

Reference Documents

Conclusion

About UIKIT_EXTERN

In development we often declare many global constants to ensure project‑wide availability. In iOS this is done with UIKIT_EXTERN, which guarantees global accessibility while preventing conflicts between dynamic libraries.

#ifdef __cplusplus
#define UIKIT_EXTERN extern "C" __attribute__((visibility ("default")))
#else
#define UIKIT_EXTERN extern __attribute__((visibility ("default")))
#endif

Many frameworks such as YYKit also use this 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
#endif

Why write it this way? What effect does it have? Which scenarios apply? The article will reveal the answers.

UIKIT_EXTERN Code Walkthrough

Interpretation 1.0 eg

如果是C++语言
那么就声明此宏定义,在C++语言里面写C需要加上C的说明,设置编译器属性为 default,保证对外部的类可见
否则
就声明此宏定义,设置编译器属性为 default,保证对外部的类可见
在这里,宏仅仅是对象宏,等量替换,后者替换前者

Principle

__attribute__

is a compiler attribute used in GNU C to describe special properties such as visibility.

Visibility controls symbol export in dynamic libraries; default makes a symbol visible, hidden hides it.

Example compilation commands and readelf output illustrate how visibility affects symbol visibility.

test2.cc 可以调用func1,原因是test1.o和test2.o同属于一个so文件(so文件是Linux下的动态库文件,等同于iOS下的动态库UIKit等)
// test1.cc file
#include <stdio.h>
extern "C" void func1();
void func1() { printf("in %s
", __FUNCTION__); }
// compile with -fvisibility=hidden
__attribute__ ((visibility("hidden"))) void func1();
// test2.cc file
extern "C" void func1();
extern "C" void func2() { func1(); printf("in %s
", __FUNCTION__); }
// main.cc file
extern "C" void func1();
extern "C" void func2();
int main() { func1(); func2(); return 0; }
// compile result
g++ -c main.cc
g++ -fvisibility=hidden -fPIC -c test1.cc
g++ -fvisibility=hidden -fPIC -c test2.cc
g++ -shared -o libvisibility.so test1.o test2.o
g++ -o test main.o -lvisibility -L .

Result: func1 has visibility set to hidden, while func2 is default, so func1 cannot be called from main() but func2 can.

Application Scenarios

Compilation optimization

Global variable declaration

Resolving conflicts between different libraries

Extensions

Macro

// concat two params
#define __SN_PASTE__(A,B) A##B

// main macro
#define SNSquare(A) __SNSQUARE_IMPL__(A,__COUNTER__)

// param counter
#define __SNSQUARE_IMPL__(A,L) ({ __typeof__(A) __SN_PASTE__(__a,L) = (A); (__SN_PASTE__(__a,L)) * (__SN_PASTE__(__a,L)); })

int res = SNSquare(3);
NSLog(@"3 square is %d",res);
关于宏,喵神写了一篇非常好的文章,这里就不再赘述,链接见文章底部。

extern

extern declares a global variable without defining it.

// ViewController.h
#import "ViewController.h"
int x = 24;

@interface ViewController ()
@end

@implementation TestViewController
- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor purpleColor];
}
@end

// BViewController.m
#import "BViewController.h"
extern int x;
- (void)viewDidLoad {
    [super viewDidLoad];
    NSLog(@"x is:%d",x); // x is 24
}
@end

Search flow: the compiler first looks in the current file; if not found, it searches other files.

static

static modifies variable scope and lifetime.

static int a = 3;
++a;
NSLog(@"a is %d",a); // a is 4

Static variables persist for the entire program lifetime and exist only once.

const

const marks a variable as read‑only.

NSString * const kTableViewCell = @"kTableViewCell";

In iOS, const variables improve pre‑compilation speed and enforce read‑only access.

iOS extern

extern can modify any variable type; multiple declarations, single definition.

// UIKIT_EXTERN example
UIKIT_EXTERN const CGFloat kAnimationInterval;
FOUNDATION_EXTERN NSString * const kAnimationKey;

// implementation
const CGFloat kAnimationInterval = 0.5f;
NSString * const kAnimationKey = @"kAnimationKey";
UIKIT_EXTERN

is defined in UIKit/UIKitDefines.h; FOUNDATION_EXTERN is defined in Foundation/NSObjCRuntime.h.

Reference Documents

Macro black magic: https://onevcat.com/2014/01/black-magic-in-macro/

YYKit usage: https://github.com/ibireme/YYKit/blob/master/YYKit/Base/YYKitMacro.h

G++ variable attributes: https://gcc.gnu.org/onlinedocs/gcc/Variable-Attributes.html

G++ function attributes: https://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html

Conclusion

关于一个小小的宏字段,引发了很多的畅想,还有一些更高级的用法,感兴趣的作者可以搜索下ReactiveCocoa这个框架,作者把宏应用到出神入化的地步,简直🐂出天际!!!技术之路需要不断输入输出,我们都是平凡人,只不过看谁坚持的久而已。
Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

iOSconstvisibilityMacrosexternstaticUIKIT_EXTERN
Sohu Smart Platform Tech Team
Written by

Sohu Smart Platform Tech Team

The Sohu News app's technical sharing hub, offering deep tech analyses, the latest industry news, and fun developer anecdotes. Follow us to discover the team's daily joys.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.