@interface声明和@property声明之间的区别

时间:2010-01-29 03:33:18

标签: objective-c iphone properties

我是C的新手,对于目标C来说是新手。对于iPhone子类,Im声明变量我想让类中的所有方法都可以看到@interface类定义,例如

@interface myclass : UIImageView {
    int aVar;
}

然后我再次声明为

@property int aVar;

然后我

@synthesize aVar;

你能帮我理解三个步骤的目的吗?我做了不必要的事吗?

感谢。

6 个答案:

答案 0 :(得分:57)

在这里,您要声明一个名为aVar的实例变量:

@interface myclass : UIImageView {
    int aVar;
}

您现在可以在班级中使用此变量:

aVar = 42;
NSLog(@"The Answer is %i.", aVar);

但是,实例变量在Objective-C中是私有的。如果您需要其他课程来访问和/或更改aVar,该怎么办?由于方法在Objective-C中是公共的,所以答案是编写一个返回aVar的访问器(getter)方法和一个设置aVar的mutator(setter)方法:

// In header (.h) file

- (int)aVar;
- (void)setAVar:(int)newAVar;

// In implementation (.m) file

- (int)aVar {
    return aVar;
}

- (void)setAVar:(int)newAVar {
    if (aVar != newAVar) {
        aVar = newAVar;
    }
}

现在其他类可以通过以下方式获取和设置aVar

[myclass aVar];
[myclass setAVar:24];

编写这些访问器和mutator方法可能会非常繁琐,因此在Objective-C 2.0中,Apple为我们简化了它。我们现在可以写:

// In header (.h) file

@property (nonatomic, assign) int aVar;

// In implementation (.m) file

@synthesize aVar;

...将自动为我们生成accessor / mutator方法。

总结一下:

  • int aVar;声明实例变量aVar

  • @property (nonatomic, assign) int aVar;aVar

  • 声明了accessor和mutator方法
  • @synthesize aVar;aVar

  • 实现了访问器和mutator方法

答案 1 :(得分:12)

这在对象中声明了一个实例变量:

@interface myclass : UIImageView {
    int aVar;
}

实例变量是您班级的私人实施细节。

如果您希望其他对象能够读取或设置实例变量(ivar)的值,您可以将其声明为属性:

@property int aVar;

这意味着编译器希望看到属性的setter和getter访问器方法。

当您使用@synthesize关键字时,您要求编译器自动为您生成setter和getter访问器方法。

因此,在这种情况下,编译器在遇到@synthesize关键字时将生成与此类似的代码:

- (int) aVar
{
    return aVar;
}

- (void)setAVar:(int)someInt
{
    aVar = someInt;
}

默认情况下,在iPhone上(以及Mac上的32位运行时),@synthesize需要一个实例变量才能存储属性的值。这个ivar通常被命名为与属性相同,但不一定是,例如你可以这样做:

@interface myclass : UIImageView {
    int aVar;
}

@property int someValue;

@synthesize someValue = aVar;

实际上既不需要@synthesize也不@property,您可以创建自己的getter和setter方法,只要您使用符合键值编码的语法创建它们,该属性仍然是可用的。

要求出现ivar以及@property声明是由于Mac和iPhone上32位Objective-C运行时的fragile base class限制。使用Mac上的64位运行时,您不需要ivar,@synthesize会为您生成一个。

请注意,您可以在@property声明中使用众多关键字来控制创建的合成访问者代码的类型,例如readonly仅适用于getter的访问者,copyatomicnonatomic等。更多信息请参见Objective-C 2.0 Programming Language文档。

答案 2 :(得分:1)

类可以包含实例变量(ivars)。它们位于第一部分,仅对该类中的代码可见,而不是任何外部代码。我喜欢在它们前面添加一个下划线来显示它们的内部性。在低级术语中,ivars作为附加成员添加到您正在创建的类在内部使用的结构中。

第二个声明@property是声明的属性。它不是必需的(除非您使用@synthesize时),但它可以帮助其他程序员(和编译器!)知道您正在处理属性,而不仅仅是两个方法-setAVar-aVar ,这是这样做的另一种方式。

第三,@synthesize实际上创建了从类外部设置和访问属性的方法。您可以使用自己的setter和getter方法替换它,但只有在需要时才这样做,因为内置的具有一些您必须自己编写代码的功能。事实上,使用@synthesize aVar = _someVariable;语法,您可以让您的属性实际引用不同命名的实例变量!

简短版本: @property只是对编译器和其他程序员的暗示,你正在创建一个属性而不仅仅是getter / setter方法。实例变量是类的内部变量,否则通常无法从外部访问。 @synthesize只为你创建简单的getter和setter,与你的@property一起使用,但你也可以自己编写那些getter和setter,就像任何其他方法一样。

答案 3 :(得分:0)

@interface在obj-c中声明类的实例变量。您需要它来创建实例变量。但是,默认情况下,该变量在类外部不可见(因为该字段默认受保护)。

@property告诉编译器指定一个特定的属性访问器(get / set)方法。但是,您需要使用@synthesize来让编译器自动生成简单的访问器,否则您需要自己创建它们。

答案 4 :(得分:0)

我最近开始学习iphone应用程序。根据我的知识,@ .property在.h文件中用作setter方法,而在.m文件中用@synthesize作为getter方法。在Java中,我们使用setter和getter方法,与Java相同,在Objective C中我们使用@property和@synthesize。

请原谅我如果你认为我误导了你。

答案 5 :(得分:0)

Class A      

      @interface myclass : UIImageView {
    int aVar;
}

If you declare like this then you can only use this variable within your class A.


But suppose in Class B

    A *object=[A new];
object.aVar---->not available



For this you should **declare aVar as a property in Class A**

so class A should look like 

Class A      

  @interface myclass : UIImageView {
    int aVar;
}
@property int iVar;


and 


.m file 
@synthesize iVar;



So now you can use this iVar in another class Suppose B


 Class B
#import "Class A.h"

    enter code here

A *object=[A new];
object.aVar---->available
means
object.aVar=10;