高效编写代码的方法(一):import之道

前言

最近买了一本Effecitve Objective-C 2.0来看,写的比较详细,决定边看边记录变分享。

头文件的导入

在Objective-C中,我们使用#import来导入另一个类的头文件。
但在编译阶段,频繁的#import 会增加编译器的编译时间。
当然可以说现在硬件设备都很好,固态硬盘速度快,随便#import不会增加多少时间的。
我觉得不管如何,高效编写代码,无论从哪个地方着手,去计较,都是不为过的。

情况一

下面说个例子:

#import <Foundation/Foundation.h>
#import "Teacher.h"

@interface HightSchoolClass : NSObject

@property (nonatomic, strong) NSString *className;

@property (nonatomic, assign) NSInteger studentsCount;

@property (nonatomic, strong) Teacher *teacher;

@end

你有一个HightSchoolClass类,还有一个Teacher类,每一个HighSchoolClass类中都有一个teacher对象,这种情况下你完全可以使用#import "Teacher.h" 来告诉HighSchoolClass去导入Teacher类。
但是这种简单的情况下,我们没有必要让HightSchoolClass类去知道Teacher类的一些详细信息,我们只需要告诉编译器,有一个类叫Teacher就行了
因此用@class teacher;是一种更加高效的方法,如下:

#import <Foundation/Foundation.h>

@class Teacher;

@interface HightSchoolClass : NSObject

@property (nonatomic, strong) NSString *className;

@property (nonatomic, assign) NSInteger studentsCount;

@property (nonatomic, strong) Teacher *teacher;

@end

这样做的好处在于节省了一次导入,也同时避免了#import HighSchool 类的另一个类也会跟着导入没有必要导入的Teacher类。

情况二:

先有鸡还是先有蛋?
在Teacher.h中我们添加一个joinClass:方法,如下:

#import <Foundation/Foundation.h>

#import "HightSchoolClass.h"

//@class HightSchoolClass;

@interface Teacher : NSObject

@property (nonatomic, strong) NSString *name;

- (void)joinClass:(HightSchoolClass *)newClass;

@end

同时在HighSchoolClass中我们也添加一个方法addTeacher:方法,如下:

#import <Foundation/Foundation.h>

#import "Teacher.h"

@interface HightSchoolClass : NSObject

@property (nonatomic, strong) NSString *className;

@property (nonatomic, assign) NSInteger studentsCount;

@property (nonatomic, strong) Teacher *teacher;

- (void)addTeacher:(Teacher *)newTeacher;

@end

注意两个类的头文件都互相#import了对方,造成了先有鸡还是先有蛋的问题。
此时@class 就能完美解决这个问题。

情况三:

导入一个含有协议的大型类。
有些时候,我们希望自己写的一个类去遵守某个协议,比如HighSchoolClass 有一个@ProtocolPatrol,旨在班级晚休时有人进行巡逻查看,巡逻的人是保安也好,老师也好,学生干部自己也好,不重要,只要遵守Patrol协议的人都能巡逻。
所以我们让HighSchoolClass声明一个协议:

#import <Foundation/Foundation.h>

#import "Teacher.h"

@protocol Partrol<NSObject>

- (void)partrol;

@end

@interface HightSchoolClass : NSObject

@property (nonatomic, strong) NSString *className;

@property (nonatomic, assign) NSInteger studentsCount;

@property (nonatomic, strong) Teacher *teacher;

- (void)addTeacher:(Teacher *)newTeacher;

@end

然后新建一个叫Security的保安类,
.h下:

#import <Foundation/Foundation.h>
#import "HightSchoolClass.h"

@interface Security : NSObject<Partrol>

@end

.m下实现patrol方法:

#import "Security.h"

@implementation Security
- (void)partrol
{
   NSLog(@"我在巡逻");
}
@end

平时的时候, 之前我都是这么去实现的,要遵守某个协议,先#import声明了这个协议的类,比如这里就必须#import HighSchoolClass
但是打个比方说,我作为巡逻的保安,我其实没那么必要去了解你那个班级有哪些学生,班主任是谁,班长是谁等等(举个例子而已)。
所以我们完全的#import HighSchoolClass就显得有些多余。

一个比较合适的解决方法就是把协议单独放在一个头文件中,或者单独写一个扩展 :

#ifndef Protocol_h
#define Protocol_h

@protocol Partrol<NSObject>

- (void)partrol;

@end

#endif /* Protocol_h */

因此在Security中只需要#import “Protocol.h”即可,而不需要import整个HightSchoolClass。这样可以减少依赖性。

但是还有一种情况是代理委托协议,也就是最常见的情况。这种情况下还是不要采用以上方式,因为协议只有与委托类放在一起才有意义。

小结

  • 1 每次Import之前仔细想一想为什么要Import ,我是否要引入整个别的类而或我只是需要让编译器知道有这个类
  • 2 遵循协议写类时,降低耦合,将协议单独书写出去。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容