@class和#import的区别
使用@class不必知道这个类里到底有什么,只要知道有这样一个类#import是把这个类里所有有的方法和属性都导入了进来,非必要情况下,使用@class可以减少类的使用者所需引入头文件的数量,也避免了引入根本用不到的内容,从而可以缩短编译时间,所以我们将引入头文件的时机尽量延后,只在确有需要时才引入。
头文件的循环引用
我们常提到头文件的循环引用,如果在A类里引入B类的头文件,当解析A类头文件时,编译器会发现他引入了B类的头文件,而B类头文件又回过头来应用A类头文件,使用#import而非#include指令虽然不会导致死循环,但却意味着这两个类里有一个无法被正确编译,@class也觉得了两个类互相引用的问题。
协议单独放在一个头文件中
有时候,必须要在头文件中引入其他头文件,如果你写的类继承自某个超类,则必须引入定义那个超类的文件。同理,如果要声明你写的类遵从某个协议,那么该协议必须有完整定义,且不能使用向前声明(@class),向前声明只能告诉编译器有某个协议,而此时编译器却要知道该协议中定义的方法,这样#import是难免的,鉴于此,最好是把协议单独放在一个头文件里。要是把协议放到某个大文件里,那么只要引入协议,就必定会引入那个头文件中的全部内容,如此一来,就会产生相互依赖问题,增加编译器时间
委托协议(delegate protocol)
然而有些协议,例如“委托协议”,就不用单独写一个头文件了,在那种情况下,协议只有与接受协议委托的类放在一起定义才有意义,此时最好能在实现文件中声明此类实现了该协议,并把这段实现代码放在“分类”。这样的话,只要在实现文件中引入包含委托协议的头文件即可,而不需要将其放在公共头文件里。
要点
1、除非却有必要,否则不要引入头文件。一般来说,应在某个类的头文件中使用先前声明来提及别的类,并在实现文件中引入那些类的头文件,这样做可以尽量降低类之间的耦合
2、有时无法使用向前声明,比如声明某个类遵循一项协议。这种情况下,尽量把“该类遵循某协议”这条声音移至分类里,如果不信的话,就把协议单独放在一个头文件中,然后将其引入。