7

このヘッダーを調べてください:

// Test.h
@interface Test : NSObject @end

extern id A;               // (0)
//extern static id B;      // (1) Uncomment to get a compiling error
extern id C;               // (2)
//extern static id D;      // (3) Uncomment to get a compiling error

そして、この実装に:

// Test.m
#import "Test.h"

id A = @"A";               // (4)
static id B = @"B";        // (5)

@implementation Test

id C = @"C";               // (6)
static id D = @"D";        // (7)

@end

// Still Test.m

@interface Test2 : NSObject @end
@implementation Test2 : NSObject

+ (void)initialize {
    NSLog(@"%@ %@", A, B); // (8)
    NSLog(@"%@ %@", C, D); // (9)
}

@end

次の質問があります。

  1. 宣言 (4) と (5) または (6) と (7) の間に根本的な違いはありますか?
  2. 「外部」宣言 (4) と実装範囲への同封 (6) に違いはありますか?
  3. 実装スコープ内で宣言された (6) と (7) が別の実装スコープ (9) でアクセスできるのはなぜですか?
  4. (2) ヘッダーで宣言された理由 (6) 実装スコープ内で宣言されたアクセスできるのはなぜですか?
  5. (1) と (3) はエラーを生成するCannot combine with previous 'extern' declaration specifierのに、(0) と (2) はエラーなしでコンパイルされるのはなぜですか?
4

1 に答える 1

7
  1. はい、staticこのコンテキストで使用すると、変数がファイルのスコープに制限されます。

    (4) がありid A = @"A"、プロジェクト内の別のファイルでextern宣言すると、ヘッダーに宣言がなくても、コンパイラ エラーが発生します。

    (5)の場合static id B = @"B"は別ファイルで宣言するとうまくいきます。

  2. いいえ、これらは C の変数宣言であり、Objective-C のスコープ規則に従っていません。

  3. Objective-C は C のスーパーセットであるため、(6) と (7) は単に C の場合と同様に宣言されたグローバル変数です。

  4. (2) は実際には (6) を参照していません。#import「信頼してください。C別のファイルで宣言されたという変数があります」と他のファイルに宣言するだけです。これは後でコンパイルされたオブジェクト ファイルがリンクされたときに解決されます。

  5. 前述のように、変数のスコープを現在のファイルに制限しているため、変数が別のファイルで宣言されているstaticと競合します。extern

于 2012-07-08T11:03:00.237 に答える