在接口部分中声明变量与在方法之外的实现部分中声明变量之间有什么区别。
答案 0 :(得分:7)
你的意思是在实施中的ivar块中,如
@implementation MyClass {
id someIvar;
}
// methods go here
@end
如果是这样,那么唯一的区别就是对其他代码的可见性。在运行时,ivar与@interface
部分中声明的ivar无法区分。但是,类外的代码可以看到@interfaces
中声明的ivars,除非这些ivars标有@protected
或@private
,否则其他类可以进入和旋转ivars。但是在@implementation
中声明的ivars在外面的代码中甚至都不可见,因此它们无法触及ivars。
在大多数情况下,这只是代码清洁问题。除非它是公开的,否则不应该在头文件中添加任何内容。那么为什么要把伊娃放在那里?
正如Josh Caswell所指出的那样,以这种方式宣称的伊娃要求最新版本的Clang。
您的问题的替代解释是您有像
这样的代码@implementation MyClass
- (void)someMethod { /* ... */ }
NSString *var;
- (void)otherMethod { /* ... */ }
@end
如果这是你的意思,那么答案是,不要这样做。在这段代码中,我们声明了一个名为var
的全局变量而不是实例变量。变量在@implementation
块内的位置是无关紧要的,它与C中的全局变量完全相同(因为它就是这样)。
答案 1 :(得分:2)
@interface
中声明的变量是实例变量。在最近的编译器中,实例变量也可以在@implementation
中的块中声明,与@interface
中的方式类似 - 这会影响其可见性但不影响其< EM>寿命
在实现中声明为“在方法之外”的变量,如:
@implementation
static int CallCount = 0;
是Objective-C最接近 class 变量的东西 - 一个类的所有实例共享的变量,而不是每个对象实例所具有的实例变量它自己的变量。
这样的变量具有执行生命周期 - 它存在于整个应用程序的整个执行过程中 - 就像典型的类变量在其他语言中一样。 (实例变量的生命周期是它们所属的对象实例的生命周期。)
使用static
进一步将变量名称的可见性(而不是其生命周期)限制为仅包含声明的文件 - 就像其他语言中的私有类变量一样。请注意,与大多数语言类变量不同,在@implementation
中没有 a static
限定符声明的变量会添加到全局命名空间中,从而增加名称冲突的机会 - 这是为什么它们不是真正的类变量。
这类变量通常使用类方法+ initialize
进行初始化,就像使用实例方法- init
初始化实例变量一样。
答案 2 :(得分:1)
在类扩展中声明它们通常用于尝试从客户端隐藏实例变量和关联的访问器。这两种方法都没有真正隐藏它们,但隐藏它们通常是一种改进,只有在您需要的所有编译器都支持它时才可用。