Fork me on GitHub

OC基础学习5:源文件组织

将程序拆分为多个小文件有助于更快地找到重要的代码,而且其他人在查看项目时也能有个大致的了解。

拆分接口和实现

根据@interface@implementation,OC的代码通常放在两种文件里:

  • 接口部分(.h):类的@interface指令、公共struct定义、enum常量、#defines和extern全局变量等。
  • 实现部分(.m): 类的@implementation指令、全局变量的定义、私有struct等。

另外,复杂的项目可以拥有多个目标,它们源文件的配置各不相同,构建规则也不同。群组关系仅仅是有Xcode负责管理的一项奇妙的功能。

拆分Car程序

  • #import 带尖号的是导入系统头文件(只读),如#import <Foundation/Foundation.h>;双引号是项目本地的代码文件,如#import "Engine.h"
  • 拆分上一篇中的Car程序
    首先拆分继承自NSObject的类:TireEngine
1
2
3
4
5
6
7
//  Tire.h

#import <Foundation/Foundation.h>

@interface Tire : NSObject

@end
1
2
3
4
5
6
7
8
9
10
11
//  Tire.m

#import "Tire.h"

@implementation Tire
//#pragma mark -
- (NSString *)description {
return (@"I am a Tire.");
} //description

@end
1
2
3
4
5
6
7
//  Engine.h

#import <Foundation/Foundation.h>

@interface Engine : NSObject

@end
1
2
3
4
5
6
7
8
//  Engine.m
#import "Engine.h"

@implementation Engine
- (NSString *)description {
return (@"I am a Engine.");
} //description
@end

使用跨文件依赖关系

  • @class 是告诉编译器:“这是一个类,只会通过指针来引用它,不需要关注此类的更多信息”。可减少必须导入的头文件的数量,从而缩短编译时间。
    拆分Car类:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    //  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
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    //  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部分。
    拆分Slant6AllWeatherRadial

    1
    2
    3
    4
    5
    6
    7
    //  Slant6.h

    #import "Engine.h"

    @interface Slant6 : Engine

    @end
    1
    2
    3
    4
    5
    6
    7
    8
    9
    //  Slant6.m

    #import "Slant6.h"

    @implementation Slant6
    - (NSString *)description {
    return (@"I am a slant-6.VROOM!");
    }
    @end
    1
    2
    3
    4
    5
    6
    7
    //  AllWeatherRadial.h

    #import "Tire.h"

    @interface AllWeatherRadial : Tire

    @end
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    //  AllWeatherRadial.m

    #import "AllWeatherRadial.h"

    @implementation AllWeatherRadial
    -(NSString *)description
    {
    return (@"I am a tire for rain or shine.");
    }
    @end

最后是main.m文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//  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;
}

坚持原创技术分享,您的支持将鼓励我继续创作!
  • 本文标题: OC基础学习5:源文件组织
  • 本文作者: AndyRon
  • 发布时间: 2017年07月22日 - 00:00
  • 最后更新: 2018年09月19日 - 23:47
  • 本文链接: http://andyron.com/2017/oc-basic-5.html
  • 版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 3.0 许可协议。转载请注明出处!