/ iOS

读书笔记《Effective Objective-C》第2条-@class

第二条 头文件中尽量少引入其他头文件

@class与编译时间

Human类的头文件中如果有成员变量Hand类,那么这个时候一般的写法:

// Human.h
#import "Hand.h"
@interface Human:NSObject
@property (nonatomic, strong) Hand *leftHand;
@property (nonatomic, strong) Hand *rightHand;
@end

但事实上,这样的做法并不是那么优雅,也不高效。先说更好的方法:

// Human.h
@class Hand;
@interface Hand:NSObject
@property (nonatomic, strong) Hand *leftHand;
@property (nonatomic, strong) Hand *rightHand;
@end
  1. 在前者代码中,#import了整个Hand类的头文件。Human类知道了许多Hand类的细节,但是在头文件中是不需要了解这些细节的。
  2. 在后者代码中,出现了@class这个东西。它被称为Forward Declaring,告诉编译器:『现在有Hand这么一个类的存在』就OK了,因为头文件并不需要知道Hand类里面有些什么方法等。
  3. 前后者相对比,编译时间绝对是后者领先的。因为后者并不需要引入那些根本用不上的东西。
  4. 当然,@class主要还是用在头文件(即.h文件)上。一般来说,实现文件(.m)是比较需要知道自己所用到的类的具体细节的。

@class也可以解决多个头文件的引入关系成环状

如果我们将每个头文件抽象成一个,头文件与头文件之间的引入关系抽象成一条有向边。那么在一个项目中,头文件互相的引入关系就可能会构成一张有向环图:

我们暂且称之为循环引入。会带来什么后果呢?

循环引入带来的后果

解析A头文件的时候会去解析B的头文件,B找C,C找D…构成了循环…子子孙孙无穷尽也2333。

这是#include会带来的后果,但Objective-C使用的是#import,#import专门避免了这种情况的出现,不会有死循环。虽然如此,但也会有某些类无法被正确编译。

知道该干啥了不~→_→其实并不是所有情况都要使用@class,比如说协议。留下一些思考的空间吧~