#pragma 预处理指令
在C/C++标准中,#pragma是一条预处理的指令(preprocessor directive)。简单地说,#pragma是用来向编译器传达语言标准以外的一些信息。
整理代码
举个简单的例子,如果我们在代码的头文件中定义了以下语句:
1 |
#pragma mark - UITableViewDelegate |
在你的 @implementation 中使用 #pragma mark 来将代码分割成逻辑区块。这些逻辑区块不仅仅使得阅读代码本身容易许多,也为Xcode源导航增加了视觉线索(#pragma mark 声明前有一个水平分割并由破折号(-)开始)。
#pragma clang diagnostic clang诊断设置
在iOS开发中,clang diagnostic(clang 诊断设置) 是#pragma的常用命令:
1 2 3 4 |
#pragma clang diagnostic push #pragma clang diagnostic ignored "-相关命令" // 你自己的代码 #pragma clang diagnostic pop |
更多相关命令,可以从http://fuckingclangwarnings.com 查到,很详细。
自定义警告
1 |
#pragma message "Warning" |
1 |
#warning "Warning 2" |
两种强制警告的方法在视觉效果上结果是一样的,但是警告类型略有不同,一个是-W#pragma-messages,另一个是-W#warnings。对于第二种写法,把warning换成error,可以强制使编译失败。比如在发布一些需要API Key之类的类库时,可以使用这个方法来提示别的开发者别忘了输入必要的信息。
1 |
#error "Something wrong" |
本文的主题并不是警告,但是想了解更多可以阅读 onecat的谈谈Objective-C的警告
屏蔽方法废弃警告
1 2 3 4 |
#pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" [TestFlight setDeviceIdentifier:[[UIDevice currentDevice] uniqueIdentifier]]; #pragma clang diagnostic pop |
屏蔽不兼容指针类型警告
1 2 3 4 |
#pragma clang diagnostic push #pragma clang diagnostic ignored "-Wincompatible-pointer-types" // #pragma clang diagnostic pop |
屏蔽循环引用警告
1 2 3 4 5 6 7 |
// completionBlock is manually nilled out in AFURLConnectionOperation to break the retain cycle. #pragma clang diagnostic push #pragma clang diagnostic ignored "-Warc-retain-cycles" self.completionBlock = ^ { ... }; #pragma clang diagnostic pop |
屏蔽未使用变量警告
1 2 3 4 |
#pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunused-variable" int a; #pragma clang diagnostic pop |
_Pragma操作符
_Pragma操作符,该操作符具有与 #pragma 指令相同的功能
1 |
_Pragma(token-string) |
相比预处理指令#pragma,_Pragma操作符可用于宏定义中的内联。 #pragma 指令不能用于宏定义中,因为编译器会将指令中的数字符号(“#”)解释为字符串化运算符 (#)。,由于_Pragma是一个操作符,因此可以用在一些宏中,我们可以看看下面这个例子:
在适配不同版本系统的适合,为了避免废弃API的警告,一般我们都使用#pragma clang diagnostic ignored "-Wunused-variable"来屏蔽警告:
1 2 3 4 |
#pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" //code #pragma clang diagnostic pop |
但是在宏定义中#pragma就不行了,在宏定义中#被用来做字符串化符号。比如如下宏:
1 2 |
#define OBJC_STRINGIFY(x) @#x #define STRINGIFY(x) #x |
STRINGIFY将任意符号,转化为字符串。STRINGIFY(example)被转化成了字符串 "example"
由于_Pragma并不带有#符号,所以使用_Pragma完美的解决问题:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_8_0 #define JK_NSDATE_UTILITIES_COMPONENT_FLAGS \ _Pragma("clang diagnostic push") \ _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"") \ ({ \ unsigned components;\ if ([UIDevice currentDevice].systemVersion.floatValue >= 8.0f){ \ components = (NSYearCalendarUnit| NSMonthCalendarUnit | NSDayCalendarUnit | NSWeekCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit | NSWeekdayCalendarUnit | NSWeekdayOrdinalCalendarUnit); \ }else{ \ components = (NSYearCalendarUnit| NSMonthCalendarUnit | NSDayCalendarUnit | NSWeekCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit | NSWeekdayCalendarUnit | NSWeekdayOrdinalCalendarUnit); \ } \ components; \ })\ _Pragma("clang diagnostic pop") \ #else #define JK_NSDATE_UTILITIES_COMPONENT_FLAGS \ _Pragma("clang diagnostic push") \ _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"") \ ({\ unsigned components = (NSYearCalendarUnit| NSMonthCalendarUnit | NSDayCalendarUnit | NSWeekCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit | NSWeekdayCalendarUnit | NSWeekdayOrdinalCalendarUnit); \ components; \ })\ _Pragma("clang diagnostic pop") \ #endif |
再比如,忽略执行的代码是否废弃
1 2 3 |
#define NS_SUPPRESS_DIRECT_USE(expr) _Pragma("clang diagnostic push") \ _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"")\ expr\ |
1 2 3 |
NS_SUPPRESS_DIRECT_USE( Foo(); ); |
Which Clang Warning Is Generating This Message
转载请注明:天狐博客 » iOS开发#pragma预处理指令与_Pragma操作符