2012-07-21 4 views
29

@interfaceが2回あるのはなぜですか? class.hに1つ、class.mに1つあります。@implementationの上に@interfaceがあるのはなぜですか?

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()があるものについて、です。それはなぜそこにあるのですか?私はそれが必要ですか?事前

+0

可能な重複[.hと.mファイルの\ @interface定義の違い](http://stackoverflow.com/questions/3967187/difference-between-interface-definition-in-h-and-m-ファイル)、[iOS 5プロジェクトで使用される.mファイルの\ @interface宣言は何ですか?](http://stackoverflow.com/questions/9751057/what-is-the-interface-declaration-in-m- ios-5プロジェクト用ファイル)、[2つのインターフェイスが* .hと* .mファイル](http://stackoverflow.com/questions/9590917)[実装ファイル内のインターフェイスを宣言する(Objective- C)](http://stackoverflow.com/questions/10647913/) –

答えて

46

第2の@interfaceディレクティブはインプリメンテーションファイル(.m)にあります。クラスのcretatorがクラスのユーザに公開したくないものを宣言するためのものです。これは、通常、プライベートおよび/または内部のメソッドとプロパティを意味します。また、これには2つのタイプがあることにも注意してください。 (あなたはここを参照してください)1は、「クラスの拡張」と呼ばれ、括弧の空の組で表されます:

@interface MyClass() 

あなたのクラスに追加のインスタンス変数を追加するためにこれを使用することができますので、この1はparticularily重要です。

もう一つは、このように、カテゴリの名前を囲み、括弧の非空のペアで示され、「カテゴリ」、と呼ばれる:

@interface MyClass (CategoryName) 

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

2

おかげでそこでは、あなたが、あなたのクラスで使用するプライベートメソッドとプロパティを宣言することができますが、他のクラスにさらしません。

3

第2の「インターフェース」は、「TestTableViewController」クラスの拡張を定義します。これは、hファイルのみをインポートするユーザーには表示されません。これは、目的Cのプライベートメソッドを作成するための事実上の方法です。

+0

いいえ、それはカテゴリではありません、それはクラスの拡張です。 -1。 –

+1

-1とはあまりうまくありません。カテゴリと拡張の違いはほとんど意味があります。拡張は基本的に匿名のカテゴリなので、クラスのメイン実装ブロックで実装する必要があります。したがって、第2の "インターフェース"ブロックのカッコ内に名前を設定すると、効果的にカテゴリーを作成し、拡張子を作成することはありません。 – dcoder

2

TestTableViewController.hファイルのインターフェイスは、クラス拡張の宣言です。これを示す2つの丸い括弧があります。構文は、クラスのカテゴリを記述する場合と同じです。しかし

この場合には、作者が公開したくないプライベートメソッドのいくつかの並べ替えを宣言するために使われているヘッダファイルで、通常のカテゴリインターフェイスは次のようになります。

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

そして、対応する実装:

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

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

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

+0

プライベートメソッドを宣言してコードを分類する以外にカテゴリを使用していますか? –

+0

ありがとうございます。今はクラス拡張と呼ばれていませんでした。私はちょうどこれまでカテゴリとして考えていました。私はそれを修正します。 –

+0

名前がなくても、まだクラスを拡張していないのですか?インスタンス変数を追加するにはどうしたらいいですか? – Honey