码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2015-01-03 13:06:20      阅读:1955      评论:0      收藏:0      [点我收藏+]

标签:

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

一、#import和#include的区别

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

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

二、关键字@class的作用

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

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

Classes.h

 1 //  
 2 //  Classes.h  
 3 //  08_@class  
 4 //  
 5 //  Created by jiangwei on 14-10-11.  
 6 //  Copyright (c) 2014年 jiangwei. All rights reserved.  
 7 //  
 8   
 9 #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

 1 /  
 2 //  Classes.m  
 3 //  08_@class  
 4 //  
 5 //  Created by jiangwei on 14-10-11.  
 6 //  Copyright (c) 2014年 jiangwei. All rights reserved.  
 7 //  
 8   
 9 #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

 1 //  Student.h  
 2 //  08_@class  
 3 //  
 4 //  Created by jiangwei on 14-10-11.  
 5 //  Copyright (c) 2014年 jiangwei. All rights reserved.  
 6 //  
 7   
 8 #import <Foundation/Foundation.h>  
 9   
10 #import "Classes.h"  
11   
12 @interface Student : NSObject{  
13     Classes *_classes;  
14 }  
15   
16 - (void)work;  
17   
18 @end 

Student.m

 1 //  
 2 //  Student.m  
 3 //  08_@class  
 4 //  
 5 //  Created by jiangwei on 14-10-11.  
 6 //  Copyright (c) 2014年 jiangwei. All rights reserved.  
 7 //  
 8   
 9 #import "Student.h"  
10   
11 @implementation Student  
12   
13 - (void)work{  
14     NSLog(@"work");  
15 }  
16   
17 @end  

在来看一下测试代码:

main.m

 1 //  
 2 //  main.m  
 3 //  08_@class  
 4 //  
 5 //  Created by jiangwei on 14-10-11.  
 6 //  Copyright (c) 2014年 jiangwei. All rights reserved.  
 7 //  
 8   
 9 #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

 1 //  
 2 //  Classes.h  
 3 //  08_@class  
 4 //  
 5 //  Created by jiangwei on 14-10-11.  
 6 //  Copyright (c) 2014年 jiangwei. All rights reserved.  
 7 //  
 8   
 9 #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

 1 //  
 2 //  Classes.m  
 3 //  08_@class  
 4 //  
 5 //  Created by jiangwei on 14-10-11.  
 6 //  Copyright (c) 2014年 jiangwei. All rights reserved.  
 7 //  
 8   
 9 #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文件,使其运行通过。

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

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

标签:

原文地址:http://www.cnblogs.com/iLillian/p/4199360.html

(1)
(2)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!