86

これら2つのクラス宣言の違いは何ですか?ここで@classが使用されている理由がわかりません。ありがとう。

@class TestClass;

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

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

4 に答える 4

203

@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は無害ですが、完全に不要です。

于 2012-04-04T22:22:40.770 に答える
18
@class TestClass;

これは単に「クラスTestClassが定義される」と宣言するだけです。

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

ただし、クラス名を使用するプロトコルを定義する場合(たとえば、デリゲートに渡されるパラメーターのタイプとして)、@class TestClassクラスはまだ定義されていないため、プロトコル定義の前に宣言する必要があります。

一般に、クラス定義を行う前にクラス名を指定する必要がある場合は、@class最初に宣言を発行する必要があります

于 2012-04-04T22:17:00.187 に答える
7

@classMattの答えによると、コード内の宣言にはまったく意味がありません。@classforwardはクラスを定義して、コンパイラーが参照している一般的な種類のユニットを後で認識できるようにします。Objective-Cは実行時にほとんどタイプレスであるため、コンパイラが実際に知る必要があるのはそれだけであることがよくあります。これは、アトミックC値と区別するのに十分です。

私は暗闇の中で突き刺し、インスタンス変数が宣言されているので、@interface古いコードを見ていると言います。これは古いコードであるため、@classおそらく別の場所にあり(たとえば、間にデリゲートプロトコルが宣言されていた)、無害に取り残されてしまいました。

于 2012-04-04T22:17:52.683 に答える
5

@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

// MyClass hasn't been defined yet, but MyClassDelegate will still compile even tho
// params mention MyClass, because of the @class declaration.
// You're telling the compiler "it's coming. don't worry".
// You can't send MyClass any messages (you can't send messages in a protocol declaration anyway),
// but it's important to note that @class only lets you reference the yet-to-be-defined class. That's all.
// The compiler doesn't know anything about MyClass other than its definition is coming eventually.

@interface MyClass : NSObject

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

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

@end

次に、クラスを使用しているときに、クラスのインスタンスを作成するだけでなく、単一のインポートステートメントでプロトコルを実装することもできます。

#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];

}
于 2015-05-13T02:01:50.243 に答える