import、#include和@class有什麼區別
- #import是Objective-C匯入標頭檔案的關鍵字
- import會包含這個類的所有資訊,包括
實體變數和方法
- 使用#import標頭檔案會自動只匯入一次,不會重複匯入,相當於#include和#pragma once
- import會包含這個類的所有資訊,包括
- #include是C/C++匯入標頭檔案的關鍵字
- @class告訴編譯器某個類的宣告,當執行時,才去檢視類的實現檔案,可以解決標頭檔案的相互包含
@class只是
告訴
編譯器,其後面宣告的名稱是類的名稱。 - #import<>用來匯入
系統
的標頭檔案,#import“”用來匯入使用者
的標頭檔案。
相互引用標頭檔案問題
- 如果有迴圈依賴關係,如:A–>B, B–>A這樣的相互依賴關係。
- 首先,兩個.m檔案互相引用.h檔案,不會出現問題的。
- 但是比如在.h裡的某個屬性,型別是自定義的類,這時候如果只在.m裡引用就編不過了。
// JTTest1.h
#import <Foundation/Foundation.h>
#import "JTTest2.h"
@interface JTTest1 : NSObject
@property (nonatomic, strong) JTTest2 *test; //!!報錯“Unknown type name 'JTTest2'; did you mean 'JTTest1'?”
@end
// JTTest2.h
#import <Foundation/Foundation.h>
#import "JTTest1.h"
@interface JTTest2 : NSObject
@end
複製程式碼
- 解決:
使用@class
。在.h檔案中使用@class,然後在.m檔案中#import "JTTest2.h"即可。
// JTTest1.h
#import <Foundation/Foundation.h>
@class JTTest2;
@interface JTTest1 : NSObject
@property (nonatomic, strong) JTTest2 *test;
@end
// JTTest1.m
#import "JTTest1.h"
#import "JTTest2.h"
@implementation JTTest1
@end
複製程式碼
- 原因:
@class JTTest2;
這句話的意思就是,告訴編譯器,確實有JTTest2
這個類,具體細節你不用管,別報錯就行了。所以顯然,到了.m
裡,它只知道有這個類,卻不知道這個類有什麼屬性,有哪些方法。所以需要在.m
再import
這個標頭檔案。
儘量在.m
而不是.h
裡使用import
引用
所以我們推薦儘量在.m
裡引用標頭檔案,而不是在.h
裡,必要時使用@class
。
在編譯效率方面考慮,如果你有100個標頭檔案都#import了同一個標頭檔案,或者這些檔案是依次引用的,如A–>B, B–>C, C–>D這樣的引用關係。當最開始的那個標頭檔案有變化的話,後面所有引用它的類都需要重新編譯,如果你的類有很多的話,這將耗費大量的時間。而是用@class則不會。
但是也有一些情況,是不可避免要在.h
裡引用的。比如:繼承某個類,必須在.h
裡 import 父類的.h
;類實現某個介面,必須在.h裡引用介面的.h
等等。