您的位置:首页 > 移动开发 > Objective-C

【Objective-C编程】import、include及@Class的孽缘

2015-08-04 22:05 656 查看
一、#import和#include

在Oc中如果#include两次的话会报错:因为#include相当于拷贝头文件中的声明内容,所以会报重复定义的错误

但是使用两次#import的话,不会报错,Oc的编译器很聪明很智能 ,他会做一次判断,如果已经导入一次就不导入了,所以他可以解决重复导入的问题

之前有说过,Oc是C语言的超集,当然#include是从C语言遗留下来的写法,虽然在OC上你可以这样写,但你永远不会这样写。

二、关键字@class的作用

在来看一下OC中的关键字@class的作用,它可以实现改变跨文件依赖关系,依赖关系指的是两个实体之间的关系,某两个类或者存在一种继承与被继承的关系,这样如果超类改变之后,子类也受到影响必须进行重新的编译,虽然Xcode上能帮我们记住这种依赖关系,在小的项目工程上的话还好影响不大,若是在大工程的话这样还是挺影响效率的,别抱怨OC,因为OC已经提供了一种方法能够减轻这种由依赖关系引起 的重新编译带来的影响。

卖了这么大的关子,现在正式对@class进行介绍.@class是一个前向引用,它的作用类似在告诉编译器:相信我,以后你自然会知道这个类到底是什么,但是现在,你知道这些足矣,也就是说如果进行前向引用而不进行导入的话这样在类中只能知道被@class的类的头文件信息,也就知道单单的接口信息。在

C++里有这样类似的前向声明,C++的前向声明形式为class A。

1.能够减轻这种由依赖关系引起 的重新编译带来的影响

2.循环依赖关系中,@class也很有用,A类引用B类,B类引用A类,如果通过import来进行导入让两个类相互引用的话则直接会编译报错,如果进行@classs则能解决这个问题

总结一下,在类中如果只是以指定形式进行引用则直接可以使用@class,如果用于继承关系的,则直接使用

三.案例

一个人里有一个鼻子与两只手,存在has-a(有一个)的关系,所以本章例子以复合为主,将鼻子与手的对象写进人这个类里。

nose类:

//接口
#import <Cocoa/Cocoa.h>
@interface Nose : NSObject
@end

//实现
#import "Nose.h"
@implementation Nose
-(NSString*) description
{
return @"一个鼻子";
}
@end
hand类:

//接口
#import <Cocoa/Cocoa.h>
@interface Hand : NSObject
@end

//实现
#import "Hand.h"
@implementation Hand
-(NSString*) description
{
return @"一个手";
};
@end
human类:

//接口
#import <Cocoa/Cocoa.h>
@class Hand;
@class Nose;

@interface Human : NSObject
{
Hand* _hands[2];
Nose* _nose;
}

@property(nonatomic) Nose* nose;
@property(readonly) Hand* hand;

-(void)setHand:(Hand *)hand:(int) index;
-(void) printf;

@end

//实现
#import "Human.h"
@implementation Human

-(void)setNose:(Nose *)nose
{
_nose =nose;
}

-(Nose*)nose
{
return _nose;
}

-(void)setHand:(Hand *)hand:(int)index
{
_hands[index]=hand;
}

-(void) printf
{
NSLog(@"%@",_nose);
NSLog(@"%@",_hands[0]);
NSLog(@"%@",_hands[1]);
}
@end

Main函数的实现:

@class Hand;                                                                                                                      @class Nose;                                                                                                                      @class Human;
int main(int argc, const char * argv[]) {

Human* human =[Human new];

Nose* nose =[Nose new];
[human setNose:nose];

for (int i=0; i<2; i++) {
Hand* hand =[Hand new];
[human setHand:hand :i];
}

[human printf];
return 0;
}
可以看到人这个类与Main函数里我们都直接用@class创建前向引用 而不是直接导入,我们可以用import也可以,但是我们完全没必要,因为有更高效率的做法等着我们,这样可以更减轻依赖关系,从而加快编译。

在human类我们只需要知道它的接口的信息便可,无需知道太多。
在main函数里,我们只是对其hand类nose类进行指针引用,所以我们可以直接使用前向引用。

如果工程的关系改为:人下面有男人与女人,有is a(是一个)的关系,使用继承的关系,则此时在main函数里就一定要用import的了,因为编译器需要事先知道超类的所有信息。

ok,关于import、include及@Class的关系就分享至此。有不对的地方还望指出互相学习。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息