7
@interface Foo : NSObject

{
    extern int gGlobalVar;   
    int i;
}
-(void)setgGlobalVar:(int)val;

@end


@implementation Foo

-(void)setgGlobalVar:(int)val
{  
    i = 5;
    NSLog(@"i = %i", i);
    gGlobalVar = val;
}

@end

インターフェイスで宣言iし、エラーなしで実装で使用できます。externしかし、インターフェイスで型の変数を宣言することはできません。これはなぜですか?「型名ではストレージ クラスを指定できません」というエラーが表示されるのはなぜですか?

4

1 に答える 1

13

簡単な説明: クラスの@interfaceORの括弧で囲まれたセクションは、インスタンス変数 (別名「ivar」)を宣言する@implementationためだけのものです。このキーワードは、グローバル変数宣言 (または関数ですが、それは別のトピックです) でのみ使用するためのものです。 したがって、extern ivar を宣言することはできません。extern

気骨のある詳細: 変数は最初に宣言され、次に定義されます。明示的な定義のないローカルで宣言された変数は、多くの場合、コンパイラによって割り当てられ、デフォルト値が与えられるため、この区別は通常、ローカル スコープ内の変数ではあいまいです。

グローバル変数は、グローバルが存在することをスコープが認識していれば、任意のスコープで使用できる可能性があります。そこでキーワードのextern出番です。グローバル変数が存在し、別の場所で定義されていることを宣言します。これは、異なるコード ファイル内のグローバル変数にアクセスする場合にのみ役立ちます。

ベスト プラクティス:externあなたの本には、実装ファイル (たとえば、".m" ファイルなど) で変数を宣言するコードがいくつか含まれています。グローバルには、実際には他の場所で有効な定義があります。(しかし、高度なコンパイラはこの種のエラーを発見します。)

代わりに、ヘッダー ファイルで extern 変数を 1 回宣言し、そのヘッダーで extern を定義するための専用の実装ファイルを用意し、そのグローバル変数を使用する他の実装ファイルにそのヘッダーを含めることをお勧めします。

于 2012-08-17T16:53:07.330 に答える