Objective-C中源文件组织章节介绍

在这一章中主要介绍的内容是如何封装代码,将代码分类组织,让开发者更容易理解整个项目.

1.拆分接口和实现部分:

  在Objective-C中我们已经知道源代码是被分成两部分:a.接口@interface;b.实现@implementation;

    接口:包含了所有使用该类所需要的信息,编译器编译@interface部分之后,就能够使用该类的对象,调用类的方法,将对象复合到其他类中和创建子类了.

    实现:@implementation部分告诉Objective-C编译器如何让该类工作,这部分代码实现了接口中声明的方法.

  由于有以上两部分,所以代码自然也就拆分为接口与实现两部分了,当然类的代码通常也分别放在两个文件中.

    存放接口代码的文件内容有:类的@interface指令、公共struct定义、enum常量、#defines和extern全局变量等。存放这些声明的文件被称为头文件(.h文件);

    存放实现代码的文件内容有:类的@implementation指令、全局变量的定义、私有struct等。此文件名与类名同名(.m文件)与存放接口的头文件有一一对应的关系.

最后这里有一点需要说明:若是以".mm"作为文件扩展名,编译器就会认为开发者是用Objective-C++来编写代码,这样就可以同时使用C++语言和Objective-C来编程了.

    组织关系只是一个由Xcode管理的虚拟工具。Xcode可以创建一个指向文件系统中某个特定目录的组,Xcode会帮助开发者将新创建文件放在该目录里.只要创建了文件,就可以在列表中双击他们来进行编辑,Xcode会自动写入一些有用的标准样本代码,这些样本代码都是通常需要包含在这些文件里的,例如#import<Cocoa/Cocoa.h>以及需要你来填充的空的@interface和@implementation部分.

说明:到目前为止,我们在程序里使用的都是#import<Foundation/Foundation.h>,因为这些程序都只用到了Cocoa的这一部分功能.但是将它替换成#import<Cocoa/Cocoa.h>也是可以的.这条语句既导入了Foundation框架的头文件,也导入了其他一些文件.

2.拆分Car程序:

  首先,需要创建继承自NSObject:的类.选择New File,然后选择Objective-C Class,输入你创建的类名;接下来从当前项目中将@interface部分剪切到你刚创建的类的头文件对应位置,同理将@implementation部分也剪切到实现文件中(.m文件)的对应位置.当然这里还有一个重要的问题就是需要将@interface的头文件部分添加到@implementation文件中去,最后在主函数main中进行调用.这就是简单的Objective-C的封装过程(有编程经验的开发者会发现这其实就是与C++等语言的封装过程一样,只是代码语法方面有小小的区别而已).头文件的尖括号与双引号的问题与C语言中是一样的。

3.使用跨文件依赖关系:

  依赖关系:是两个实体之间的一种关系。在编程开发当中这种关系不仅出现在类与类之间,也可以出现在文件与文件之间。依赖关系是可以传递的,头文件也可以相互依赖,所以在重新编译的时候可能会导致花费很长时间,Xcode至少帮助开发者记录了所有依赖关系。

  a.重新编译须知: 在Objective-C中提供了一种方法能够减少由于依赖关系引起的重新编译所带来的影响,依赖关系的问题的存在是因为Objective-C编译器需要某些信息才能够工作。有时候编译器需要知道类的全部信息,而有些时候编译器只需要知道类名即可(不需要了解类的整个定义)。在这里就需要提到一个@class指令了:@class创建了一个前向引用,就是在告诉编译器:"相信我,以后你就会知道这个类到底是什么,但是现在,你只需要知道这些."若是有循环依赖@class也很有用,即A类使用B类,B类也使用A类,若是试图通过#import语句让这两个类相互引用,那么最后就会出现编译错误,但是若在A.h中使用@class B,在B.h中使用@class A,那么这两个类就可以相互引用了.

  b.导入和继承:拆分出来的文件不能使用@class指令是因为他们是继承自其他类而不是通过指针指向其他类,所以不能在头文件中使用@class语句.开发者职能在这里使用#import指令.搞清楚@class指令为什么不能在这里使用,是因为编译器需要先知道所有关于超类的信息才能成功的为其子类编译@interface,它需要了解超类实例变量的配置(数据类型、大小和排序)。在子类中添加实例变量时,他们它们会被附加在超类实例变量的后面,然后编译器用这条信息来判断在内存的什么位置能找到这些实例变量,从每个方法调用自身的self隐藏指针开始寻找,为了能够准确地计算出实例变量的位置,编译器必须先了解该类的所有内容.

最后总结:了解组织源代码基本技巧,通常每个类都有两个文件:包含类@interface部分的头文件和包含@implementation部分的".m文件".类的使用者可以导入(使用#import指令)头文件来获得该类的功能.这章介绍认识了跨文件依赖关系.在这种关系中,头文件和源文件需要使用另一个头文件中的信息,文件之间相互重复的导入会增加编译次数,也会导致不必要的重复编译,而巧妙的利用@class指令能够减少编译时间,@class可以减少不得不导入的头文件数量.

posted on 2011-11-17 20:16  呓语若梦半浮生  阅读(777)  评论(0编辑  收藏  举报

导航