2012-07-08 127 views
7

请看看这个标题:Objective-C中的不同静态变量声明如何?

// 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)编译时没有错误?

回答

7
  1. 是,static在该上下文中使用的限制变量的文件的范围。

    如果您在项目的另一个文件中有(4)并声明id A = @"A",即使没有在头文件中声明extern,您也会遇到编译器错误。

    在(5)的情况下,如果您在另一个文件中声明static id B = @"B",那么它将正常工作。

  2. 不,这些是C变量声明,不遵循Objective-C范围规则。

  3. 由于目标C是C的超集,(6)和(7)被简单地全局变量声明如他们将在C.

  4. (2)并没有真正引用(6) ,它只是向其他文件声明它“相信我,在另一个文件中声明了一个名为C的变量”,稍后在编译的目标文件链接时解析该文件。

  5. 如前所述static限制变量的范围到当前文件,因此它与extern冲突,该变量声明该变量是在另一个文件中声明的。

+0

哇,你摇滚。谢谢! – Stream 2012-07-08 11:12:07