將程序拆分為多個小文件有助于更快地找到重要的代碼,而且其他人在查看項目時也能有個大致的了解。
拆分接口和實現
根據@interface
和@implementation
,OC的代碼通常放在兩種文件里:
- 接口部分(.h):類的@interface指令、公共struct定義、enum常量、#defines和extern全局變量等。
- 實現部分(.m): 類的@implementation指令、全局變量的定義、私有struct等。
另外,復雜的項目可以擁有多個目標,它們源文件的配置各不相同,構建規則也不同。群組關系僅僅是有Xcode負責管理的一項奇妙的功能。
拆分Car程序
#import
帶尖號的是導入系統頭文件(只讀),如#import <Foundation/Foundation.h>
;雙引號是項目本地的代碼文件,如#import "Engine.h"
。-
拆分上一篇中的Car程序
首先拆分繼承自NSObject
的類:Tire
和Engine
。// Tire.h #import <Foundation/Foundation.h> @interface Tire : NSObject @end
// Tire.m #import "Tire.h" @implementation Tire //#pragma mark - - (NSString *)description { return (@"I am a Tire."); } //description @end
// Engine.h #import <Foundation/Foundation.h> @interface Engine : NSObject @end
// Engine.m #import "Engine.h" @implementation Engine - (NSString *)description { return (@"I am a Engine."); } //description @end
使用跨文件依賴關系
-
@class
是告訴編譯器:“這是一個類,只會通過指針來引用它,不需要關注此類的更多信息”。可減少必須導入的頭文件的數量,從而縮短編譯時間。
拆分Car
類:// Car.h #import <Foundation/Foundation.h> @class Engine; @class Tire; @interface Car : NSObject - (Engine *) engine; - (void) setEngine: (Engine *) newEngine; - (Tire *) tireAtIndex: (int) index; - (void) setTire: (Tire *) tire atIndex: (int) index; - (void)print; @end //Car
// Car.m #import "Car.h" #import "Tire.h" #import "Engine.h" @implementation Car { Engine *engine; Tire *tires[4]; } - (Engine *) engine { return (engine); } //engine - (void) setEngine:(Engine *)newEngine { engine = newEngine; } //setEngine - (void) setTire:(Tire *)tire atIndex:(int)index { if (index<0 || index>3) { NSLog(@"bad index (%d) in setTire:atIndex", index); exit(1); } tires[index] = tire; } // setTire - (Tire *) tireAtIndex:(int)index { if (index<0 || index>3) { NSLog(@"bad index (%d) in setTire:atIndex", index); exit(1); } return tires[index]; } // tireAtIndex - (id)init { if (self = [super init]) { //? engine = [Engine new]; tires[0] = [Tire new]; tires[1] = [Tire new]; tires[2] = [Tire new]; tires[3] = [Tire new]; } return (self); } - (void)print { NSLog(@"%@", engine); NSLog(@"%@", tires[0]); NSLog(@"%@", tires[1]); NSLog(@"%@", tires[2]); NSLog(@"%@", tires[3]); } @end //Car
-
編譯器需要先知道所有關于超類的信息才能成功地為其子類編譯@interface部分。
拆分Slant6
和AllWeatherRadial
:// Slant6.h #import "Engine.h" @interface Slant6 : Engine @end
// Slant6.m #import "Slant6.h" @implementation Slant6 - (NSString *)description { return (@"I am a slant-6.VROOM!"); } @end
// AllWeatherRadial.h #import "Tire.h" @interface AllWeatherRadial : Tire @end
// AllWeatherRadial.m #import "AllWeatherRadial.h" @implementation AllWeatherRadial -(NSString *)description { return (@"I am a tire for rain or shine."); } @end
最后是main.m
文件:
// main.m
#import <Foundation/Foundation.h>
#import "Car.h"
#import "Tire.h"
#import "Engine.h"
#import "Slant6.h"
#import "AllWeatherRadial.h"
int main(int argc, const char * argv[]) {
Car *car = [Car new];
Engine *engine = [Slant6 new];
[car setEngine:engine];
for (int i=0; i<4; i++) {
Tire *tire = [AllWeatherRadial new];
[car setTire:tire atIndex:i];
}
[car print];
return 0;
}