6

我讀過你應該嘗試在你的頭文件中使用@class而不是#import,但是當你的@class包含你正在嘗試的委託協議時,這不起作用使用。使用@class訪問委託協議聲明

MyView.h

#import <UIKit/UIKit.h> 
@class MyCustomClass; // <-- doesn't work for MyCustomClassDelegate, used below 

@interface MyView : UIView <MyCustomClassDelegate> 

@end 

我想我忽視的東西,有沒有辦法讓@class在這種情況下工作,或者是#import我唯一的選擇?

編輯:解決此問題的一個方法是,在.m文件的專用接口部分中聲明您的#import MyCustomClass和MyCustomClassDelegate,而不是.h文件。

回答

5

你只能向前聲明在同一個頭文件的協議對方法的返回值用法或參數類型。在你的情況下,你希望類符合協議,所以它不會工作,因爲它定義了將添加到類本身(即它將響應的方法)的行爲。

因此,您必須#import該協議。出於這個原因,將協議和類拆分成單獨的文件可能是一個好主意。有關更多信息,請參閱this answer

+2

不是爲了剔除坑,而是更確切地說:你可以轉發 - 聲明一個協議,但是如果你聲明瞭一個符合該協議的類(在該頭文件中),則不能。如果協議僅用於方法返回或參數類型,那麼聲明它就可以了(並且您使用「@protocol MyProtocol;」而不是「@class MyProtocol;」來執行此操作)。 – erikprice

+0

更新,謝謝澄清! – Senseful

4

MyCustomClassDelegate是一個協議,而不是一個類。告訴編譯器關於MyCustomClass的存在告訴它沒有任何關於協議的存在。

2

您需要在上課前申報您的代理協議:

MyCustomClass.h:

#import <UIKit/UIKit.h> 
@class MyCustomClass; 

@protocol MyCustomClassDelegate <NSObject> 

- (void)myCustomClass:(MyCustomClass *)customClass 
       didBlah:(BOOL)blah; 

@end 

@interface MyCustomClass : NSObject <MyCustomClassDelegate> 

@end 

而且你甚至不能用@protocol以前瞻申報委託協議;編譯器必須看到完整的聲明,因此會更改@class一個#import

MyView.h:

#import <UIKit/UIKit.h> 
#import "MyCustomClass.h" // the compile now knows what MyCustomClassDelegate is 

@interface MyView : UIView <MyCustomClassDelegate> 

@end 
+1

ehhh?我認爲他意味着協議已經在他所引用的類中聲明過了,所以不需要再聲明它。 – Bot

+0

@Bot啊,是的,他只需要使用'#import'而不是'@ class'。我的錯。 – trojanfoe

9

可以使用@protocol轉發宣佈的協議,如果你只需要它的變量,比如這個:

@protocol MyProtocol; 

@interface MyClass { 
    id<MyProtocol> var; 
} 
@end 
你的情況

類是試圖以符合一個協議,所以必須瞭解它。 我認爲你的選擇是把協議分成它自己的文件和#import這個頭文件,或者在使用它的類聲明上面的那個頭文件中聲明協議。

它通常不需要太多擔心#包括一個類文件,如果它的一部分框架等。