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

Nig*_*l 29 iphone properties objective-c

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

@interface myclass : UIImageView {
    int aVar;
}
Run Code Online (Sandbox Code Playgroud)

然后我再次宣布它为

@property int aVar;
Run Code Online (Sandbox Code Playgroud)

然后我

@synthesize aVar;
Run Code Online (Sandbox Code Playgroud)

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

谢谢.

Ste*_*son 57

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

@interface myclass : UIImageView {
    int aVar;
}
Run Code Online (Sandbox Code Playgroud)

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

aVar = 42;
NSLog(@"The Answer is %i.", aVar);
Run Code Online (Sandbox Code Playgroud)

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

// 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;
    }
}
Run Code Online (Sandbox Code Playgroud)

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

[myclass aVar];
[myclass setAVar:24];
Run Code Online (Sandbox Code Playgroud)

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

// In header (.h) file

@property (nonatomic, assign) int aVar;

// In implementation (.m) file

@synthesize aVar;
Run Code Online (Sandbox Code Playgroud)

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

总结一下:

  • int aVar; 声明一个实例变量 aVar

  • @property (nonatomic, assign) int aVar; 声明了accessor和mutator方法 aVar

  • @synthesize aVar; 实现了accessor和mutator方法 aVar


Rob*_*ger 12

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

@interface myclass : UIImageView {
    int aVar;
}
Run Code Online (Sandbox Code Playgroud)

实例变量是类的私有实现细节.

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

@property int aVar;
Run Code Online (Sandbox Code Playgroud)

这意味着编译器期望查看属性的setter和getter访问器方法.

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

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

- (int) aVar
{
    return aVar;
}

- (void)setAVar:(int)someInt
{
    aVar = someInt;
}
Run Code Online (Sandbox Code Playgroud)

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

@interface myclass : UIImageView {
    int aVar;
}

@property int someValue;

@synthesize someValue = aVar;
Run Code Online (Sandbox Code Playgroud)

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

对ivar和@property声明的要求是由于Mac和iPhone上32位Objective-C运行时的基类限制很脆弱.使用Mac上的64位运行时,您不需要ivar,@synthesize为您生成一个.

请注意,有很多关键词,你可以用你用@property声明来控制哪些是创建的合成访问代码排序,如readonly对于仅消气访问,copy,atomic,nonatomic等等.更多信息在Objective-C 2.0编程语言文档中.