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