#include与#import的区别以及@class


OC学习篇之---@class关键字的作用以及#include和#import的区别

分类: IOS2014-12-06 13:093747人阅读评论(0)收藏举报

 
前一篇文章说到了OC中类的三大特性:http://blog.csdn.net/jiangwei0910410003/article/details/41707161今天我们来看一下在学习OC的过程中遇到的一些问题,该如何去解决,首先来看一下我们之前遗留的一个问题:

 


一、#import和#include的区别


当我们在代码中使用两次#include的时候会报错:因为#include相当于拷贝头文件中的声明内容,所以会报重复定义的错误

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

 


二、关键字@class的作用

在来看一下OC中的关键字@class的作用,在看他的作用之前,先来看一个问题:

现在有一个课程类Classes和学生类Student,他们两之间需要相互引用(导入)。直接看代码比较直接:

Classes.h

 


[objc] view plaincopy
01.// 
02.//  Classes.h 
03.//  08_@class 
04.// 
05.//  Created by jiangwei on 14-10-11. 
06.//  Copyright (c) 2014年 jiangwei. All rights reserved. 
07.// 
08. 
09.#import <Foundation/Foundation.h> 
10. 
11.#import "Student.h" 
12. 
13.//不会将Student.h拷贝过来,只是告诉编译器Student这个类在别的地方中有定义,这样就不知道这个类中任何信息(哪些属性和方法) 
14.//@class Student; 
15. 
16.@interface Classes : NSObject{ 
17.     
18.@public 
19.    Student *_student; 
20.} 
21. 
22.- (void)t1; 
23. 
24.@end 

导入Student.h头文件

 


Classes.m

 


[objc] view plaincopy
01.// 
02.//  Classes.m 
03.//  08_@class 
04.// 
05.//  Created by jiangwei on 14-10-11. 
06.//  Copyright (c) 2014年 jiangwei. All rights reserved. 
07.// 
08. 
09.#import "Classes.h" 
10. 
11.//#import "Student.h" 
12. 
13.@implementation Classes 
14. 
15.- (void)t1{ 
16.    [_student work]; 
17.} 
18. 
19.@end 

 


在来看一下Student类
Student.h

 


[objc] view plaincopy
01.//  Student.h 
02.//  08_@class 
03.// 
04.//  Created by jiangwei on 14-10-11. 
05.//  Copyright (c) 2014年 jiangwei. All rights reserved. 
06.// 
07. 
08.#import <Foundation/Foundation.h> 
09. 
10.#import "Classes.h" 
11. 
12.@interface Student : NSObject{ 
13.    Classes *_classes; 
14.} 
15. 
16.- (void)work; 
17. 
18.@end 
同样的也导入Classes.h头文件

 

Student.m

 


[objc] view plaincopy
01.// 
02.//  Student.m 
03.//  08_@class 
04.// 
05.//  Created by jiangwei on 14-10-11. 
06.//  Copyright (c) 2014年 jiangwei. All rights reserved. 
07.// 
08. 
09.#import "Student.h" 
10. 
11.@implementation Student 
12. 
13.- (void)work{ 
14.    NSLog(@"work"); 
15.} 
16. 
17.@end 

 


在来看一下测试代码:

main.m

 


[objc] view plaincopy
01.// 
02.//  main.m 
03.//  08_@class 
04.// 
05.//  Created by jiangwei on 14-10-11. 
06.//  Copyright (c) 2014年 jiangwei. All rights reserved. 
07.// 
08. 
09.#import <Foundation/Foundation.h> 
10. 
11.#import "Classes.h" 
12.#import "Student.h" 
13. 
14.//Classes和Student相互导入会出现问题 
15.//这时候我们就可以使用@class解决这样的问题 
16.//我们一般在.h文件中使用@class,因为在.h文件中一般是不会使用类的属性和方法的 
17.//在.m文件中可以导入.h文件 
18.int main(int argc, const charchar * argv[]) { 
19.    @autoreleasepool { 
20.        Classes *cls =[[Classes alloc] init]; 
21.        Student *stu = [[Student alloc] init]; 
22.        cls->_student = stu; 
23.        [cls t1]; 
24.         
25.    } 
26.    return 0; 
27.} 
这里有一个问题注意一下:我们看到了这里是如何使用Classes中的属性_student的,因为在Classes类中属性_student是@public的,所以可以直接使用,用的是箭头符号,和C/C++中的指针变量调用差不多。记住了,这里就说到了如何直接访问一个类中的@public修饰符的属性变量

 


我们编译运行:


看到了,编译错误,说在Student类中的Classes类找不到指定类型,这就奇怪了,我们不是导入了Classes.h文件了,为什么还是找不到类型呢?

这就是OC中类的相互引用的问题,我们在Student.h文件中导入了Classes.h,又在Classes.h文件中导入了Student.h,OC中在相互导入的时候编译是不通过的

这样就会导致错误。

当然解决办法就是使用@class关键字,我们修改一下Classes类

Classes.h

 

 

[objc] view plaincopy
01.// 
02.//  Classes.h 
03.//  08_@class 
04.// 
05.//  Created by jiangwei on 14-10-11. 
06.//  Copyright (c) 2014年 jiangwei. All rights reserved. 
07.// 
08. 
09.#import <Foundation/Foundation.h> 
10. 
11.//#import "Student.h" 
12. 
13.//不会将Student.h拷贝过来,只是告诉编译器Student这个类在别的地方中有定义,这样就不知道这个类中任何信息(哪些属性和方法) 
14.@class Student; 
15. 
16.@interface Classes : NSObject{ 
17.     
18.@public 
19.    Student *_student; 
20.} 
21. 
22.- (void)t1; 
23. 
24.@end 
我们将#import "Student.h"代码注释了,使用

@class Student

这段代码的作用就是不会将Student.h文件拷贝过来,只是告诉编译器Student这个类在别的地方中有定义,这样就不知道这个类中的任何信息了(哪些属性和方法)

Classes.m

 

 

[objc] view plaincopy
01.// 
02.//  Classes.m 
03.//  08_@class 
04.// 
05.//  Created by jiangwei on 14-10-11. 
06.//  Copyright (c) 2014年 jiangwei. All rights reserved. 
07.// 
08. 
09.#import "Classes.h" 
10. 
11.#import "Student.h" 
12. 
13.@implementation Classes 
14. 
15.- (void)t1{ 
16.    [_student work]; 
17.} 
18. 
19.@end 
然后在Classes.m文件中导入#import "Student.h"文件,这时候编译就不会报错了,同样就可以正常的运行了:

 

总结

这一篇文章就介绍了#import关键字和@class的作用,特别是@class关键字的使用,为了解决相互导入的问题,在此回顾一下我们是怎么操作的:

Student类中的导入Classes.h方式不变,在Classes.h头文件中使用@class关键字引入Student类型,使其编译通过,然后在Classes.m文件中导入Student.h文件,使其运行通过。

以后遇到这样的问题解决方法就是这样操作的。

 

 

 


版权声明:本文为博主原创文章,未经博主允许不得转载。
 
.
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值