请查看此标题:
// 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
我有以下问题:
- 声明(4)和(5)或(6)和(7)之间有什么根本区别吗
- "外部"声明(4)和所附的实施范围(6)之间有什么区别吗
- 为什么在实现范围内声明的(6)和(7)可以在另一个实现范围(9)中访问
- 为什么在头中声明的(2)可以访问在实现范围内声明的(6)
- 为什么(1)和(3)生成错误
Cannot combine with previous 'extern' declaration specifier
,而(0)和(2)编译时没有错误
-
是的,在此上下文中使用的
static
将变量限制在文件的范围内。如果在项目的另一个文件中有(4)并声明
id A = @"A"
,即使头中没有extern
声明,也会出现编译器错误。在(5)的情况下,如果您在另一个文件中声明
static id B = @"B"
,那么它将正常工作。 -
不,这些是C变量声明,不遵循Objective-C作用域规则。
-
由于Objective-C是C的超集,(6)和(7)只是像在C中一样声明的全局变量。
-
(2) 并没有真正引用(6),它只是向
#import
的其他文件声明"相信我,在另一个文件中声明了一个名为C
的变量",稍后在链接编译的对象文件时解析该变量。 -
如前所述,
static
将变量的范围限制在当前文件中,因此它与extern
冲突,后者表示变量在另一个文件中声明。