有一个巨大的区别。
在@interface
或@implementation
后面的方括号中的变量是实例变量。这些变量与您的类的每个实例相关联,因此可以在实例方法中的任何地方访问。
如果您不使用方括号声明变量,则声明的是全局变量。无论这些变量在@implementation
指令之前还是之后声明,都将成为全局变量。需要避免使用全局变量,因为它们不是线程安全的(可能会导致难以调试的错误),而应该使用全局常量。(当然也可以声明全局变量)
事实上,在Objective-C和编译器的最初版本中,您只能在.h
文件的@interface
后面的方括号中声明实例变量。
@interface YourClass : ParentClass
{
int ivar1;
}
-(void)printIVar;
@end
int someGlobalVariable;
@implementation YourClass
int someOtherGlobalVariable;
-(void)printIVar
{
NSLog(@"ivar = %d", ivar1);
}
只有现代编译器才能让你在类拓展(在.m实现文件中的@interface YourClass()
)或@implementation
中声明实例变量(仍然用括号括起来),除了可以在.h
中的@interface
之后声明它们的可能性。这样做的好处是将这些实例变量从类的外部用户中隐藏起来,通过在.m文件中声明而不是在.h文件中声明它们,因为类的用户不需要知道类的内部编码细节,只需要知道公共API。
最后一个建议:苹果越来越推荐直接使用@property
而不是实例变量,并让编译器(使用@synthesize
指令或者现代LLVM编译器隐式生成)生成内部备份变量。所以你通常不需要声明实例变量,因此可以省略@interface
指令后的空的{ }
的语法:
@interface YourClass : ParentClass
@property(nonatomic, assign) int prop1;
-(void)printProp;
@end
@implementation YourClass
-(void)printProp
{
NSLog(@"ivar = %d", self.prop1);
}
@implementation
内部使用ivar块”选项(而不是@interface
)是仅在几年前添加的。 - Nicolas Miari