预处理指令#pragram
#pragma介绍
#pragma是一个预处理指令,pragma的中文意思是『编译指示』。它不是Objective-C中独有的东西(貌似在C/C++中使用比较多),最开始的设计初衷是为了保证代码在不同编译器之间的兼容性,但随着时间推移,它出现在了更多更丰富的应用场景中。
#pragma代码是在编译期间处理的;它既不属于注释,也不属于逻辑代码的一部分;并且它和其他预处理命令譬如#ifdef ... #endif不同,它不会影响代码在运行时的逻辑处理,所以#pragma指令丝毫不会影响到程序在运行时的性能。根据Mattt Thompson大神的描述,在当前Xcode开发环境中,#pragma主要有两个应用场景:组织代码和屏蔽编译警告。
#pragma mark组织代码
组织代码是个人卫生问题,个人卫生不好(代码组织不好)不能反映人品(技术能力),但它在某种程度中影响了别人是否愿意和他搞基(合作)。在一个项目(尤其是多人合作的项目)中,应该有一个比较好的内部一致性编码习惯,不好的习惯或者缺乏一致性,会使得项目难以维持,协作也不便(这点笔者深有体会,笔者目前的项目有一个同事,编码能力尚可,但编码习惯实在太糟糕,代码紧凑,从来不空格,更妄谈空行和注释了,甚至经常不对齐,看他的代码,一点修改的欲望都没有,想的只是自己重写一遍=_=)。
在组织代码时充分使用#pragma mark就是写出『干净代码』的一个重要环节,就像这样:
#pragma mark - UIViewController
- (void)viewDidLoad {
[super viewDidLoad];
}
- (void)dealloc {
}
#pragma mark - IBAction
- (IBAction)loginNow:(id)sender {
}
#pragma mark - UITableViewDataSource
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return ;
}
#pragma mark - UITableViewDelegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
}
上述代码中使用#pragma mark将@implementation中的代码(方法)分成了几个逻辑section,这种处理并没有改变程序逻辑,但我们在使用Xcode代码导航工具时可以在视觉上汲取片刻的欢愉:

组织N个方法为一个section的依据是什么呢?这个就见仁见智了。一般来说:
- 将一个protocol的方法组织成一个section;
- 将target-action类型方法组织成一个section;
- 将notification相关方法组织成一个section;
- 将需要override的父类方法组成成一个section;
#pragma屏蔽编译警告
使用#pragma mark来组织代码使用比较普遍,相对而言,使用#pragma指令屏蔽编译器和静态分析器的警告相对来说就比较新鲜了。
You know what is even more annoying than poorly-formatted code? Code that generates warnings. 编译警告很可恶,应该尽可能修改代码干掉这些警告,但是有些时候有些警告无法避免,譬如我们在编写@selector(aMethodName)这样的代码时,如果aMethodName没有在上下文中出现,可能会出现含有『undeclared-selector』关键词的warning,有洁癖的程序员会想到干掉这个warning,此时#pragma指令就派上用场了。譬如:
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wundeclared-selector"
if ([self.selectedViewController respondsToSelector:@selector(isReadyForEditing)]) {
boolNumber = [self.selectedViewController performSelector:@selector(isReadyForEditing)];
}
#pragma clang diagnostic pop
这是Clang编译器提供的一种解决方案,通过使用#pragma clang diagnostic push/pop来告诉编译器仅仅为某一特定部分代码(记得要在代码片段末尾使用pop将最初的diagnostic设置恢复哦)忽视特定警告。
上述示例中#pragma clang diagnostic ignored后面的"-Wundeclared-selector"指示的是『特定警告』,再别的应用场景中肿么知道该填写什么呢?网络是强大的,有一个(可能是N个)愤怒的网友对clang警告消息做了一个总结,之所以说这个网友“愤怒”,是因为其链接非常有意思:http://fuckingclangwarnings.com/
Finally, you can read more about the LLVM’s use of #pragma in the Clang Compiler User’s Manual.
最后,感谢大神Mattt Thompson,本文的参考资料完全来自于《#pragma》,本来想用自己的语言完成这篇博客,边读边写,最后发现几乎差不多了,没留下啥自己的东西,就这样吧!
参考资料
- 《#pragma》;
- 《clang diagnostics》;
预处理指令#pragram的更多相关文章
- 预处理指令#pragma
#pragma介绍 #pragma是一个预处理指令,pragma的中文意思是『编译指示』.它不是Objective-C中独有的东西(貌似在C/C++中使用比较多),最开始的设计初衷是为了保证代码在不同 ...
- C/C++预处理指令#define,#ifdef,#ifndef,#endif…
2016年12月29日更新: 今天查看以前文件的时候, 突然发现了#error 这个预处理指令.然后回想一下工作, 发现这个指令使用场景还是很多的.比如: 一个项目的模块儿之多,源文件之大,代码之多, ...
- Effective Objective-C 2.0 — 第四条:多用类型常量,少用#define预处理指令
第四条:多用类型常量,少用#define预处理指令 使用#define 预处理的坏处:定义出来的常量没有类型信息,编译器只是会在编译前据此执行查找与替换操作.即使有人重新定义了常量值,编译器也不会产生 ...
- VC中预处理指令与宏定义详解
刚接触到MFC编程的人往往会被MFC 向导生成的各种宏定义和预处理指令所吓倒,但是预处理和宏定义又是C语言的一个强大工具.使用它们可以进行简单的源代码控制,版本控制,预警或者完成一些特殊的功能. 一个 ...
- C#中的预处理指令
C#中的预处理指令 作为预处理中的一对:#region name ,#endregion可能是大家使用得最多的,我也常用它来进行代码分块,在一个比较长的cs文件中,这么做确实是一件可以让你使代码更清晰 ...
- C#学习笔记(十五):预处理指令
C#和C/C++一样,也支持预处理指令,下面我们来看看C#中的预处理指令. #region 代码折叠功能,配合#endregion使用,如下: 点击后如下: 条件预处理 条件预处理可以根据给出的条件决 ...
- iOS预处理指令
预处理过程扫描源代码,对其进行初步的转换,产生新的源代码提供给编译器.可见预处理过程先于编译器对源代码进行处理. 预处理指令是以#开头的代码行,#后是指令关键字,在关键字和#号之间允许存在任意个数的空 ...
- #pragma预处理指令讲解
在所有的预处理指令中,#Pragma 指令可能是最复杂的了,它的作用是设定编译器的状态或者是指示编译器完成一些特定的动作.#pragma指令对每个编译器给出了一个方法,在保持与C和C++语言完全兼容的 ...
- C# 预处理指令
导读 1.什么是预处理 2.预处理的好处 3.C#中的常见预处理指令 4.总结 什么是预处理 在计算机科学中,预处理通常是指利用某一程序(通常是预处理器)对某一格式的源码(如.cs C ...
随机推荐
- hdu4888 多校B 最大流以及最大流唯一判断+输出方案
题意,给一个矩阵,告诉你每行和.每列和,并且限制所填数不大于k,问矩阵是否唯一. 经典建图不说了,第一次遇到判断最大流唯一性的,学习了:用dfs来判断残网中是否还存在环,若存在,则表明绕这个环走一圈, ...
- Influx kafka
http://www.opscoder.info/kafka-influxdb.html
- Raft算法详解
一致性算法Raft详解 背景 熟悉或了解分布性系统的开发者都知道一致性算法的重要性,Paxos一致性算法从90年提出到现在已经有二十几年了,而Paxos流程太过于繁杂实现起来也比较复杂,可能也是以为过 ...
- BS版代码生成器 简介
自用的代码生成器 核心:JdbcTemplate+freemarker 目前支持sqlserver和mysql 演示: 1.首界面 2.读数据库中的所有表 3.打开某数据库下的所有表.视图.存储过程 ...
- Java利用Mybatis进行数据权限控制
权限控制主要分为两块,认证(Authentication)与授权(Authorization).认证之后确认了身份正确,业务系统就会进行授权,现在业界比较流行的模型就是RBAC(Role-Based ...
- 【spring boot jpa】hql语句报错 :antlr.NoViableAltException: unexpected token: roleName
使用场景:在spring data jpa下使用@Query("hql语句") 然后在项目启动的时候报错 hql语句报错:antlr.NoViableAltException: u ...
- sshd登录攻击
先说简单的防范措施: 1.密码足够复杂 密码的长度大于8位.有数字.大小写字母.特殊字符组合. 2.nmap 扫描 为了避免被扫描到, #看到端口是81 ssh root@192.168.1.63 玩 ...
- UVA 1482 - Playing With Stones(SG打表规律)
UVA 1482 - Playing With Stones 题目链接 题意:给定n堆石头,每次选一堆取至少一个.不超过一半的石子,最后不能取的输,问是否先手必胜 思路:数值非常大.无法直接递推sg函 ...
- 华夏互联总经理汪照发接受程序猿杂志专訪-2014年6月江西IDC排行榜
作为软件开发界最权威的期刊,<程序猿>杂志一直是业界推崇的高端读物,能被其採訪是极大的荣耀. 上个月,作为江西省内的排名第一的站点开发企业和专业的站点研发厂商,Zoomla!逐浪CM ...
- 使用 C# 开发智能手机软件:推箱子(四)
这是"使用 C# 开发智能手机软件:推箱子"系列文章的第四篇. 在这篇文章中,介绍 Common/FindPath.cs 源程序文件. using System; using Sy ...