#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文件,使其運行通過。

以後遇到這樣的問題解決方法就是這樣操作的。

 

 

 


版權聲明:本文爲博主原創文章,未經博主允許不得轉載。
 
.
 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章