2012-04-04 3 views
67

これら2つのクラス宣言の違いは何ですか?なぜ@classがここで利用されているのか分かりません。ありがとう。Objective-C:@classディレクティブ@interfaceの前に?

@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としか定義されていないインスタンス参照に対してメソッドを呼び出すことはできませんでした。これは、コンパイラが使用できる追加のメタデータがないためです(コールサイトをコールとして評価するid)。

例では、@classは無害ですが、まったく必要ありません。

+17

私はちょうど 'chicken、meet egg'のためにもう1つの+1を与えることができたらいいのに – lukya

+4

ところで、それは 'id'評価に戻ります。 – jheld

+0

いくつかの人が.hファイルに '@ class'を入れ、.mファイルに必要なヘッダファイルをインポートする理由と、現在のクラスヘッダファイルに.hファイルをインポートするだけの理由がありますか?ちょうど好奇心、おかげで。 @bbum –

15
@class TestClass; 

これ単に "TestClassを定義されるクラス" を宣言します。

この場合(貼り付けたもの)、これは何の影響もありませんので、これらは同じです。

しかし、クラス名を使用するプロトコルを定義する場合(たとえば、委譲に渡されるパラメータのタイプとして)、プロトコル定義の前に@class TestClassを宣言する必要があります。まだ定義されていません。一般的に

、あなたはクラス定義が行われる前に、あなたのクラス名を言及する必要がある場合、あなたはあなたのコード内で@class宣言へのポイントは絶対にありませんマットの答えを1として

+0

IVEでプロトコルを実装することができ、両方のこの実装はプロトコルの前に最も多く実装されています。共有いただきありがとうございます! – SleepsOnNewspapers

6

最初@class宣言を発行する必要があります。 @class forwardはクラスを定義します。その結果、コンパイラはあなたが参照しているユニットの一般的な並べ替えを後で知ります。 Objective-Cは実行時にタイプ無しであるため、コンパイラが実際に知る必要があるのはたいていの場合です.Aの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]; 

} 
関連する問題