大きな違いがあります。
@interface
またはの直後の括弧内の変数@implementation
はインスタンス変数です。これらは、クラスの各インスタンスに関連付けられた変数であるため、インスタンス メソッドのどこからでもアクセスできます。
括弧を入れない場合は、グローバル変数を宣言します。ブラケット ブロックの外側で宣言された変数は、これらの変数が@implementation
ディレクティブの前後にあるかどうかにかかわらず、グローバル変数になります。また、グローバル変数は悪であり、絶対に避ける必要があります (グローバル定数を宣言できますが、グローバル変数は避けてください)。特に、それらはスレッドセーフではないため (したがって、デバッグが面倒なバグを生成する可能性があります)。
@interface
実際、歴史的に (Objective-C とコンパイラの最初のバージョンでは)、インスタンス変数は、.h
ファイル 内の後に括弧で囲んで宣言することしかできませんでした。
// .h
@interface YourClass : ParentClass
{
// Declare instance variables here
int ivar1;
}
// declare instance and class methods here, as well as properties (which are nothing more than getter/setter instance methods)
-(void)printIVar;
@end
// .m
int someGlobalVariable; // Global variable (bad idea!!)
@implementation YourClass
int someOtherGlobalVariable; // Still a bad idea
-(void)printIVar
{
NSLog(@"ivar = %d", ivar1); // you can access ivar1 because it is an instance variable
// Each instance of YourClass (created using [[YourClass alloc] init] will have its own value for ivar1
}
@interface YourClass ()
.m 実装ファイル内のクラス拡張内または .m内でインスタンス変数@implementation
を宣言できるのは、最新のコンパイラのみ@interface
です.h
。クラスのユーザーは内部コーディングの詳細を認識する必要がないため、.h ファイルではなく .m ファイルで宣言することにより、これらのインスタンス変数をクラスの外部ユーザーから隠すことができるという利点があります。ただし、パブリック API を知る必要があるだけです。
最後のアドバイス: インスタンス変数を使用する代わりに、Apple はますます@property
直接使用することを推奨し、コンパイラー@synthesize
に内部バッキング変数を生成させます (ディレクティブを明示的に使用するか、最新の LLVM コンパイラーでは暗黙的に)。そのため、最後にインスタンス変数を宣言する必要は通常まったくないため、ディレクティブの{ }
後の空を省略します。@interface
// .h
@interface YourClass : ParentClass
// Declare methods and properties here
@property(nonatomic, assign) int prop1;
-(void)printProp;
@end
// .m
@implementation YourClass
// @synthesize prop1; // That's even not needed with modern LLVM compiler
-(void)printProp
{
NSLog(@"ivar = %d", self.prop1);
}