------<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文件

  1. //
  2. //prefix header for all source flies of the 'Simple Mac App'
  3. //target in the 'Simple Mac App' project
  4. //
  5. #ifdef _OBJC_
  6. #import <Cocoa/Cocoa.h>
  7. #endif

上述代码检测_OBJC_是否被定义了。标识符前面和后面的双下划线,是一种命名规则,表明这是一个内部的值。在本例中,Objective—C环境中定义_OBJC_.如果该标志符是已定义的话,将会引入Cocoa框架,这就涉及了另一个指令:#import。

  1. //
  2. //prefix header for all source flies of the 'Simple ios App'
  3. //target in the 'Simple ios App' project
  4. //
  5. #import <availability.h>
  6.  
  7. #ifndef _IPHONE_3_0
  8. #warning "This project uses features only available in iOS SDK
  9. 3.0 and later."
  10. #endif
  11. #ifdef_OBJC_
  12. #import <UIKit/UIKit.h>
  13. #import <Foundation/Foundation.h>
  14. #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编译器指令的更多相关文章

  1. 浅谈Objective—C中的面向对象特性

    Objective-C世界中的面向对象程序设计 面向对象称程序设计可能是现在最常用的程序设计模式.如何开发实际的程序是存在两个派系的-- 面向对象语言--在过去的几十年中,很多的面向对象语言被发明出来 ...

  2. 浅谈JSP中include指令与include动作标识的区别

    JSP中主要包含三大指令,分别是page,include,taglib.本篇主要提及include指令. include指令使用格式:<%@ include file="文件的绝对路径 ...

  3. 浅谈对JIT编译器的理解。

    1. 什么是Just In Time编译器? Hot Spot 编译 当 JVM 执行代码时,它并不立即开始编译代码.这主要有两个原因: 首先,如果这段代码本身在将来只会被执行一次,那么从本质上看,编 ...

  4. 浅谈有趣的 //go: 指令

    前言 如果你平时有翻看源码的习惯,你肯定会发现.咦,怎么有的方法上面总是写着 //go: 这类指令呢.他们到底是干嘛用的? 今天我们一同揭开他们的面纱,我将简单给你介绍一下,它们都负责些什么 go:l ...

  5. 浅谈AngularJS中的指令和指令间的相互通信

    说到AngularJS,我们首先想到的大概也就是双向数据绑定和指令系统了,这两者也是AngularJS中最为吸引人的地方.双向数据绑定呢,感觉没什么好说的,那么今天我们就来简单的讨论下AngularJ ...

  6. 浅谈objective—C管理内存

    这段时间被导师催着论文,调试各种BUg,也是醉了,发现很大程度上,内存出错,栈溢出,各种悲剧.那么今天就和大家一起对OC的内存管理来个探微吧.Objective-C使用一个保留计数记录了我们所创建的所 ...

  7. 转:浅谈C/C++中的指针和数组(一)

    再次读的时候实践了一下代码,结果和原文不一致 error C2372: 'p' : redefinition; different types of indirection 不同类型的间接寻址 /// ...

  8. [C#]6.0新特性浅谈

    原文:[C#]6.0新特性浅谈 C#6.0出来也有很长一段时间了,虽然新的特性和语法趋于稳定,但是对于大多数程序猿来说,想在工作中用上C#6.0估计还得等上不短的一段时间.所以现在再来聊一聊新版本带来 ...

  9. 【微信小程序项目实践总结】30分钟从陌生到熟悉 web app 、native app、hybrid app比较 30分钟ES6从陌生到熟悉 【原创】浅谈内存泄露 HTML5 五子棋 - JS/Canvas 游戏 meta 详解,html5 meta 标签日常设置 C#中回滚TransactionScope的使用方法和原理

    [微信小程序项目实践总结]30分钟从陌生到熟悉 前言 我们之前对小程序做了基本学习: 1. 微信小程序开发07-列表页面怎么做 2. 微信小程序开发06-一个业务页面的完成 3. 微信小程序开发05- ...

随机推荐

  1. selenium 速查手册 python版

    1.安装与配置 pip install selenium 基本使用selenium都是为了动态加载网页内容用于爬虫,所以一般也会用到phantomjs mac下如果要配置phantomjs环境的话 e ...

  2. 仿qq空间相册的图片批量上传

    效果: 转载请注明:http://www.cnblogs.com/TheViper/ 主要是flash组件的tilelist,这个很有用.还有对flash组件源码的一点修改hack. 还是代码很简单, ...

  3. Robotlegs2 学习笔记 -- SwiftSuspenders 2.x (1)

    Swiftsuspenders2 是一个基于元数据(metadata)的IOC(控制反转,inversion of control)的AS3的解决方案.反转控制又被称依赖注射(Dependency I ...

  4. 慕课网-安卓工程师初养成-4-8 Java循环语句之 do...while

    do...while 循环与 while 循环语法有些类似,但执行过程差别比较大. 语法:  执行过程: <1>. 先执行一遍循环操作,然后判断循环条件是否成立 <2>. 如果 ...

  5. VC获取并修改计算机屏幕分辨率(MFC)

    //检测当前分辨率 int Width = GetSystemMetrics(SM_CXSCREEN); int Height = GetSystemMetrics(SM_CYSCREEN); DEV ...

  6. IIS装好了无法访问localhost

    解决办法:                 [1]:                 检查你的DTC服务(全名:Distributed Transaction Coordinator)是否可以正常启动 ...

  7. Compilation failed: this version of PCRE is not compiled with PCRE_UTF8 support at offset 0

    在安装pcre-8.13.tar.gz时候出了错,说是缺少libpcre.so.0 下面是解决方法.真不容易哦,一个问题来没解决,新问题就出来了.一环扣一环,会搞死去.. errorgrep: err ...

  8. Linq把一个DataTable根据一列去除重复数据

    DataTable dt_temp = dt.AsEnumerable().Cast<DataRow>().GroupBy(p => p.Field<string>(&q ...

  9. SSH环境搭建步骤解析

    一.建立Java web project:AngelSSH 二.引入jar包,必要清单如下 2.1,Struts2 commons-fileupload  文件上传组件 commons-io   io ...

  10. [JFinal 1] JFinal和SSH中使用拦截器的对比

    导读:先前在做.NET项目时,拦截的功能主要是依靠缓存session来实现.当需要跳转到某个页面,使用某个功能查询一些数据时,会根据session中的用户值来判断是否已经正常登录,如果没有,则重定向到 ...