web-dev-qa-db-ja.com

なぜ@implementationの上に@interfaceがあるのですか?

なぜ_@interface_が2度あるのかと思います。 1つは_class.h_にあり、もう1つは_class.m_にあります。例えば:

_TestTableViewController.h_:

_#import <UIKit/UIKit.h>

@interface TestTableViewController : UITableViewController

@end
_

そして(自動生成)_class.m_私は見つける:

_#import "TestTableViewController.h"

@interface TestTableViewController ()

@end

@implementation TestTableViewController

... methods delegated from UITable delegates

@end
_

だから私の質問は、_.m_ファイルの@interface TestTableViewController ()が何であるかということです。なぜそこにあるのですか?必要ですか?

前もって感謝します

37
Matej

二番目 @interfaceディレクティブは実装ファイル(.m)にあります-クラスの作成者がクラスのユーザーに公開したくないものを宣言するためのものであることから、それを推測できます。これは通常、プライベートおよび/または内部メソッドとプロパティを意味します。また、これには2つのタイプがあることに注意してください。 1つ(ここに表示されます)は「クラス拡張」と呼ばれ、括弧の空のペアで示されます。

@interface MyClass ()

これを使用してクラスにインスタンス変数を追加できるため、これは特に重要です。

「カテゴリ」と呼ばれる2番目のものは、次のように、空ではない括弧のペアで示され、カテゴリの名前を囲みます。

@interface MyClass (CategoryName)

また、クラスの拡張にも使用されます。カテゴリを使用してインスタンス変数をクラスに追加することはできませんが、同じクラスに複数のカテゴリを設定することができます。そのため、主に、ソースコードがないシステム/フレームワーククラスを拡張するために使用されます。この意味で、カテゴリはクラス拡張の正反対です。

54
user529758

2番目の「インターフェース」は、「TestTableViewController」クラスの拡張を定義します。これは、hファイルをインポートするだけの人には見えません。これは、Objective Cでプライベートメソッドを作成するための事実上の方法です。

3
dcoder

そこでは、クラスでのみ使用し、他のクラスには公開しないプライベートメソッドとプロパティを宣言できます。

2
DrummerB

TestTableViewController.hファイルのインターフェースは、クラス拡張の宣言です。これを示す2つの丸かっこがあります。構文は、クラスのカテゴリを記述する場合と同じです。ただし、この場合は、作成者がヘッダーファイルで公開したくない何らかのプライベートメソッドを宣言するために使用されます。

通常のカテゴリインターフェイスは次のようになります。

@interface TestTableViewController (Your_Category_Name)
- (void)doSomething;
@end

そして対応する実装:

@implementation TestTableViewController (Your_Category_Name)
-(void)doSomething {
// Does something...
}
@end

あなたの例ではカテゴリ名が指定されていないので、それはクラスを拡張するだけで、通常の実装でメソッドを実装できます。

通常、この手法はメソッドを「隠す」ために使用されます。これらはヘッダーファイルで宣言されておらず、.hファイルのみをインポートする場合は表示されません。

2
Sandro Meier