Objective-C中变量声明的区别

6

我正在阅读有关iOS 6中CoreImage的教程。在那个教程中,我发现了如下内容:

@implementation ViewController {
    CIContext *context;
    CIFilter *filter;
    CIImage *beginImage;
    UIImageOrientation orientation;
}
//Some methods
@end

变量在 @implementation 声明后的括号中声明。我第一次看到这种变量声明方式。
上述变量声明方式和以下代码有什么区别吗?
@implementation ViewController

    CIContext *context;
    CIFilter *filter;
    CIImage *beginImage;
    UIImageOrientation orientation;

//Some methods

@end

请重新标记它。这是针对特定编程语言的,与 iOS iOS5 Xcode4.5 无关。此外,这一直是 objC 和 C++ 工作的方式(iOS1-6)。 - Daij-Djan
@Daij-Djan:好的,已经完成了 :) 我在 iOS 6 中看到了这个功能,所以我加了那个标签。 - Midhun MP
@Daij-Djan 我非常确定“在@implementation内部使用ivar块”选项(而不是@interface)是仅在几年前添加的。 - Nicolas Miari
Op在实现中没有ivars。没有花括号。而且静态变量始终得到支持。 - Daij-Djan
@Daij-Djan:没有花括号???你能检查一下第一个代码片段吗? - Midhun MP
抱歉,我读错了 ;) 但是我没有回答。 - Daij-Djan
2个回答

21

有一个巨大的区别。

@interface@implementation后面的方括号中的变量是实例变量。这些变量与您的类的每个实例相关联,因此可以在实例方法中的任何地方访问。

如果您不使用方括号声明变量,则声明的是全局变量。无论这些变量在@implementation指令之前还是之后声明,都将成为全局变量。需要避免使用全局变量,因为它们不是线程安全的(可能会导致难以调试的错误),而应该使用全局常量。(当然也可以声明全局变量)


事实上,在Objective-C和编译器的最初版本中,您只能在.h文件的@interface后面的方括号中声明实例变量。

// .h
@interface YourClass : ParentClass
{
    // Declare instance variables here
    int ivar1;
}
// declare instance and class methods here, as well as properties (which are nothing more than getter/setter instance methods)
-(void)printIVar;
@end

// .m
int someGlobalVariable; // Global variable (bad idea!!)

@implementation YourClass

int someOtherGlobalVariable; // Still a bad idea
-(void)printIVar
{
    NSLog(@"ivar = %d", ivar1); // you can access ivar1 because it is an instance variable
    // Each instance of YourClass (created using [[YourClass alloc] init] will have its own value for ivar1
}

只有现代编译器才能让你在类拓展(在.m实现文件中的@interface YourClass())或@implementation中声明实例变量(仍然用括号括起来),除了可以在.h中的@interface之后声明它们的可能性。这样做的好处是将这些实例变量从类的外部用户中隐藏起来,通过在.m文件中声明而不是在.h文件中声明它们,因为类的用户不需要知道类的内部编码细节,只需要知道公共API。


最后一个建议:苹果越来越推荐直接使用@property而不是实例变量,并让编译器(使用@synthesize指令或者现代LLVM编译器隐式生成)生成内部备份变量。所以你通常不需要声明实例变量,因此可以省略@interface指令后的空的{ }的语法:

// .h
@interface YourClass : ParentClass

// Declare methods and properties here
@property(nonatomic, assign) int prop1;
-(void)printProp;
@end

// .m
@implementation YourClass
// @synthesize prop1; // That's even not needed with modern LLVM compiler
-(void)printProp
{
    NSLog(@"ivar = %d", self.prop1);
}

0

这是声明私有变量的一种方式,它们不会在类外可见,也不会显示在头文件中


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接