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