浅谈Objective-C编译器指令
------<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! -------
下载Xcode后,使用Max OS X Cocoa Application 模板创建一个新项目之后,就会得到一个如图所示的项目。可能需要打开其中的某些组(记住文件夹图标表示Xcode中的一个组,而不是磁盘上的一个文件夹)但基本界面与下图类似。在开发过程中,一些文件可能被重命名或者被其他文件所取代,但整个结构将保持不变。
Products组可能会以红色显示应用。红色的文件名表明文件缺失,在构建项目之后,应用文件会变回黑色,表明这个文件现在已经在磁盘上。
警告 :跟踪缺失的文件
当其他文件一个显示红色时是一个警告信息,若使用一个模板创建一个新的项目,并且除产品之外的其他文件缺失,那么这表明一定出了某种错误,需要退出Xcode,删除项目,然后重新创建项目。
项目会包括这种各样的文件,文件的扩展名,表明了文件的类型~
Plist文件是属性列表文件,这些XML文件包含一个存储键/值,plist文件被广泛应用于存储应用的设置信息,通过修改项目设置可以间接更新这些文件,如上图
预编译头文件(.pch)能够包含prefix头,这些prefix头回自动被包含进每个文件的编译结果中。与plist一样,通过项目中的相关界面可以更新这些文件,但需要修改默认设置的情况很少。.pch文件包含了编译器指令,这是很重要的内容。
在C语言(以及其他语言中),.h文件通常作头文件,它们在Objective—C中也充当着同样的角色。Objective—C是基于消息的,实现消息指令的文件(即包含头文件的实现代码的文件)的扩展名为.m
使用编译器指令
新建的项目中的文件都是比较小的,因此很容易就能掌握其结构和内容,所有这些文件都使用了编译器指令,因此以这些文件作为切入点来分析编译器指令时一个明智的决定。
编译器指令时编译器在编译文件之前,执行的一组指令,因此它们有些时候也被成为预处理指令或者预处理命令。
1.使用基本指令
本文主要介绍的是很多指令的基础构建模块是定义指令:#define。
宏定义最简单的形式是定义一个字符串替换,如:
#define pi 3.14159265
允许编写下面这样的代码。
X= pi * 2;
在开始编译之前,这行代码会转换为
X=3.14159265 * 2;
另一种形式的宏定义允许定义一个类函数的宏,宏中可以包含一个或多个值,在代码中调用宏时可以提供相应的值。
尽管宏定义是一种处理硬编码诸如pi之类的常量的便捷方式,但他们还可以用于指示是否存在特定的功能。当宏定义用于检测某项功能是否存在时,我们所关注的就只有特定标识符是否被定义成了宏。因此一下代码
#def pi
仅仅测试pi是否被定义成了一个宏,它不会输出任何值。当作宏为标记使用时通常会根据一些标志符,是否被定义过来选择处理或不处理一段代码。
2.Prefix头初探
现在可以查看prefix头了,程序清单,给出了,创建简单的Mac应用时自动生成的.pch文件
//
//prefix header for all source flies of the 'Simple Mac App'
//target in the 'Simple Mac App' project
//
#ifdef _OBJC_
#import <Cocoa/Cocoa.h>
#endif
上述代码检测_OBJC_是否被定义了。标识符前面和后面的双下划线,是一种命名规则,表明这是一个内部的值。在本例中,Objective—C环境中定义_OBJC_.如果该标志符是已定义的话,将会引入Cocoa框架,这就涉及了另一个指令:#import。
//
//prefix header for all source flies of the 'Simple ios App'
//target in the 'Simple ios App' project
//
#import <availability.h> #ifndef _IPHONE_3_0
#warning "This project uses features only available in iOS SDK
3.0 and later."
#endif
#ifdef_OBJC_
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#endif
在C中一个常见的指令是#include,它用来在编译时将一个外部文件包含进待编译文件,就好像该外部文件是待编译文件的一部分。#include指令存在一个问题是很容易造成循环引用从而会造成代码(特别是声明)被避免上述问题,如果一个文件已经被引入了,那么第二个,#import指令不会起作用。
Objective—C编译器在编译程序清单中的代码中将Cocoa框架的Cocoa.h文件引入进来。<和>表示该文件是来自框架的——本例是Cocoa框架。
简单程序清单Ios应用的Prefix头
这个prefix头首先会无条件的引入一个文件,然后没有像前面的的例子那样检测是否定义了标志符_OBJC_,相反,它检测是否未定义某些标识符。在ios3.0的SDK中会定义_IPHONE_3_0。如果标识符为被定义,那么在预处理过程中会生成一个警告信息。在检测完版本之后,它与前面的例子一样是检测是否处于Objective—C环境中,在本例中如果处于Objecttive—C环境中将引入不同的文件。
3.main.m中的普通C代码初探
不管采用MacOS或是iOS模板,使用Objective—C编译器可以编译普通的C代码,操作系统将会调用main.h文件中的main函数以启动应用。
4.浅探使用Objective—C编译器指令是以@打头,它通常用来描述文件中的内容。如在.h文件中@interface指令用来标示文件的接口代码的起始位置,而@end指令标示该段的结束位置。在.m文件中,@implementation指令用来标示实现的起始位置,@end标志结束位置。@protocolMyprotocol,这些实体会在代码中其他位置定义。
Objective—C中字符串使用@进行分隔的,如
@”This is a String”
这里的@符号提醒编译器后面是一个字符串。
小结:
Prefix头的作用是——它们通常包含用来确定哪些代码需要进行编译的宏定义,如果,根据所安装的SDK的版本来进行条件编译。
浅谈Objective-C编译器指令的更多相关文章
- 浅谈Objective—C中的面向对象特性
Objective-C世界中的面向对象程序设计 面向对象称程序设计可能是现在最常用的程序设计模式.如何开发实际的程序是存在两个派系的-- 面向对象语言--在过去的几十年中,很多的面向对象语言被发明出来 ...
- 浅谈JSP中include指令与include动作标识的区别
JSP中主要包含三大指令,分别是page,include,taglib.本篇主要提及include指令. include指令使用格式:<%@ include file="文件的绝对路径 ...
- 浅谈对JIT编译器的理解。
1. 什么是Just In Time编译器? Hot Spot 编译 当 JVM 执行代码时,它并不立即开始编译代码.这主要有两个原因: 首先,如果这段代码本身在将来只会被执行一次,那么从本质上看,编 ...
- 浅谈有趣的 //go: 指令
前言 如果你平时有翻看源码的习惯,你肯定会发现.咦,怎么有的方法上面总是写着 //go: 这类指令呢.他们到底是干嘛用的? 今天我们一同揭开他们的面纱,我将简单给你介绍一下,它们都负责些什么 go:l ...
- 浅谈AngularJS中的指令和指令间的相互通信
说到AngularJS,我们首先想到的大概也就是双向数据绑定和指令系统了,这两者也是AngularJS中最为吸引人的地方.双向数据绑定呢,感觉没什么好说的,那么今天我们就来简单的讨论下AngularJ ...
- 浅谈objective—C管理内存
这段时间被导师催着论文,调试各种BUg,也是醉了,发现很大程度上,内存出错,栈溢出,各种悲剧.那么今天就和大家一起对OC的内存管理来个探微吧.Objective-C使用一个保留计数记录了我们所创建的所 ...
- 转:浅谈C/C++中的指针和数组(一)
再次读的时候实践了一下代码,结果和原文不一致 error C2372: 'p' : redefinition; different types of indirection 不同类型的间接寻址 /// ...
- [C#]6.0新特性浅谈
原文:[C#]6.0新特性浅谈 C#6.0出来也有很长一段时间了,虽然新的特性和语法趋于稳定,但是对于大多数程序猿来说,想在工作中用上C#6.0估计还得等上不短的一段时间.所以现在再来聊一聊新版本带来 ...
- 【微信小程序项目实践总结】30分钟从陌生到熟悉 web app 、native app、hybrid app比较 30分钟ES6从陌生到熟悉 【原创】浅谈内存泄露 HTML5 五子棋 - JS/Canvas 游戏 meta 详解,html5 meta 标签日常设置 C#中回滚TransactionScope的使用方法和原理
[微信小程序项目实践总结]30分钟从陌生到熟悉 前言 我们之前对小程序做了基本学习: 1. 微信小程序开发07-列表页面怎么做 2. 微信小程序开发06-一个业务页面的完成 3. 微信小程序开发05- ...
随机推荐
- 解决 window server2008 r2 没有注册Ofiice组件的方法
解决 window server2008 r2 没有注册Ofiice组件的方法 .NET下在用Microsoft.Office.Interop.Excel及word 操作Excel和Word时, ...
- <关于数据仓库>基于docker的Mysql与Hadoop/Hive之间的数据转移 (使用Apache Sqoop™)
原创博客,转载请联系博主! 摘要:本文介绍了如何使用docker快速搭建一个可以从外部访问的mysql服务容器,和由docker搭建的分布式Hadoop文件系统,并且使用ApacheSqoop完成将m ...
- Flex 使用列表和表格
Flex 设计了不同的控件来实现列表和表格,不仅能够将数据显示在表格和列表中,还可以实现对数据进行操纵,修改等更加强大的功能. 与列表和表格相关的控件如下所示: 列表控件(List Control): ...
- kubernetes学习笔记1
安装篇 Downloading Kubernetes You can either build a release from sources or download a pre-built relea ...
- eclipse打开出错 Error: opening registry key 'Software\JavaSoft\Java Runtime Environment'
eclipse出现注册错误:①在“打开”输入框中输入“regedit”命令,删除注册表的HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\ 的INSTALLDIR删除. 或者 ...
- 关于Oracle的rac集群和mysql Galera Cluster的想法
到了新公司,公司用的是rac,我比较熟悉mysql第三方的集群方案Galera Cluster这类多主集群, 下面是我参考了他人对rac的介绍,然后和mysql方案进行的臆测级别的分析对比. rac和 ...
- jQuery遍历 slice()方法
今天做页面,遇到一个滚动的swipe,需要4个<li> 一组,然后在外层加个<ul>,方法如下: $('.xxxxx li').each(function(n){ $('.xx ...
- 【MySQL】TokuDB引擎初探(MySQL升级为Percona,MySQL升级为MariaDB)
参考:http://blog.sina.com.cn/s/blog_4673e6030102v46l.html 参考:http://hcymysql.blog.51cto.com/5223301/14 ...
- C++ STL 简单记录
1,STL提供三种类型的组件:容器.迭代器.算法. 容器: 顺序容器(vector.list.deque.string等)是一系列元素的有序集合: 关联容器(set.multiset.map.mult ...
- (图 BFS)走迷宫
题目: 给一个迷宫,求出从起点到终点的路径.迷宫 src.txt 文件内容如下,第一行是迷宫的行列数,后面行是迷宫,1表示可行走,0表示不可以通过,起点是最左上角,终点是最右下角: 解析: 其实就是图 ...