2012-04-04 48 views
67

這兩個類聲明有什麼區別?我不明白爲什麼在這裏使用@class。謝謝。Objective-C:@interface之前的@class指令?

@class TestClass; 

@interface TestClass: UIView { 
    UIImage *image1; 
    UIImage *image2; 
} 

@interface TestClass: UIView { 
    UIImage *image1; 
    UIImage *image2; 
} 

回答

165

@class存在以打破循環依賴關係。假設你有A和B級。

@interface A:NSObject 
- (B*)calculateMyBNess; 
@end 

@interface B:NSObject 
- (A*)calculateMyANess; 
@end 

雞;見蛋。這永遠不能編譯,因爲A的接口依賴於B被定義,反之亦然。

因此,它可以是固定的,通過使用@class

@class B; 
@interface A:NSObject 
- (B*)calculateMyBNess; 
@end 

@interface B:NSObject 
- (A*)calculateMyANess; 
@end 

@class有效告訴這樣一類存在某處,因此,聲明指針以指向所述類的實例是完全有效的編譯器。然而,你不能調用一個實例引用的方法,它的類型只被定義爲@class,因爲沒有額外的元數據可供編譯器使用(我不記得它是否將呼叫站點恢復爲通過呼叫評估或者不是)。

在你的例子中,@class是無害的,但完全沒有必要。

+17

我希望我可以給另一個+1只爲'雞,滿足蛋' – lukya 2013-07-05 13:25:44

+4

順便說一句,它確實恢復到'id'評估。 – jheld 2014-05-21 16:19:05

+0

爲什麼某些人在他們的.h文件中放入'@ class',然後在.m文件中導入必要的頭文件,以及其他人可能只是將當前類頭文件中的.h文件導入?只是好奇,謝謝。 @bbum – 2014-05-30 20:01:01

15
@class TestClass; 

這只是宣稱 「類的TestClass將被定義爲」。

在這種情況下(你粘貼的那個)這個沒有任何影響,所以這些都是一樣的。

但是,如果您要定義一個使用您的類名的協議(例如傳遞給委託的參數類型),您需要在協議定義之前聲明@class TestClass,因爲您的類是仍未定義。

一般來說,如果你需要的是由類定義之前提到你的類名,你將需要發出@class聲明第一

+0

我見過落實協議這個實現是最大的 - 在協議之前。感謝分享! – SleepsOnNewspapers 2015-02-10 22:29:20

6

按照馬特的答案絕對沒有點在代碼中@class聲明。 @class forward定義了一個類,以便編譯器隨後知道您指的是什麼類型的單位。由於Objective-C在運行時幾乎是無類型的,通常編譯器實際需要知道的僅僅是將它與原子C值區分開來。

我要在黑暗中進行刺探,並說因爲實例變量在@interface中聲明,所以您正在查看一些舊代碼。因爲它是舊代碼,@class可能曾經是別的地方(例如,有一個委託協議聲明),並最終被無害地擱淺。

1

當你需要爲一個對象定義一個協議時,@class會非常方便,該對象通常會與你定義的接口的對象進行交互。使用@class,您可以將協議定義保留在類的標題中。這種授權模式經常用在Objective-C上,通常最好定義「MyClass.h」和「MyClassDelegate.h」。這可能會導致一些混亂的進口問題

@class MyClass; 

@protocol MyClassDelegate<NSObject> 

- (void)myClassDidSomething:(MyClass *)myClass 
- (void)myClass:(MyClass *)myClass didSomethingWithResponse:(NSObject *)reponse 
- (BOOL)shouldMyClassDoSomething:(MyClass *)myClass; 
- (BOOL)shouldMyClass:(MyClass *)myClass doSomethingWithInput:(NSObject *)input 

@end 

@interface MyClass : NSObject 

@property (nonatomic, assign) id<MyClassDelegate> delegate; 

- (void)doSomething; 
- (void)doSomethingWithInput:(NSObject *)input 

@end 

然後,當你使用這個類,你既可以創建類的實例以及與一個import語句

#import "MyClass.h" 

@interface MyOtherClass()<MyClassDelegate> 

@property (nonatomic, strong) MyClass *myClass; 

@end 

@implementation MyOtherClass 

#pragma mark - MyClassDelegate Protocol Methods 

- (void)myClassDidSomething:(MyClass *)myClass { 

    NSLog(@"My Class Did Something!") 

} 

- (void)myClassDidSomethingWithResponse:(NSObject *)response { 

    NSLog(@"My Class Did Something With %@", response); 

} 

- (BOOL)shouldMyClassDoSomething { 

    return YES; 

- (BOOL)shouldMyClassDoSomethingWithInput:(NSObject *)input { 

    if ([input isEqual:@YES]) { 

     return YES; 

    } 

    return NO; 

} 


- (void)doSomething { 

    self.myClass = [[MyClass alloc] init]; 
    self.myClass.delegate = self; 
    [self.myClass doSomething]; 
    [self.myClass doSomethingWithInput:@0]; 

} 
相關問題