Objective C中的属性究竟是什么?属性和实例变量之间有什么区别?

时间:2012-04-12 11:19:38

标签: iphone objective-c

我对实例变量和属性非常困惑。我已经阅读了有关此事的帖子数量,但我仍然不清楚。 我来自JAVA背景,我从目标C文档中推断出,属性类似于JAVA BEAN CLASS(一个具有实例变量的getter和setter)。 属性可以通过其getter和setter方法从其他类访问,而实例变量是私有的,无法从其他类访问。

我是否正确地朝着这个方向思考?

7 个答案:

答案 0 :(得分:4)

与Java的并行非常好。唯一的区别是Objective C提供了一种访问属性的方法,就好像它是一个变量,而Java则没有。另一个区别是,在Objective C中,您可以合成属性,而在Java中,您需要手动编写getter和setter。

属性是getter方法或一对getter和setter方法的“语法糖”。属性通常(但不总是)实例变量支持,但它们可以以任何可以实现无参数实例方法的方式实现。

答案 1 :(得分:2)

好的,实例变量和属性相距很远。实例变量是对象的状态,属性是该状态的assecor方法(getter / setter)(实例变量)。

因此,无论何时在头文件中创建属性。编译器将这些属性转换为accessor方法。假设您声明了属性 - @property(nonatomic, assign, readwrite) NSString *name; 因此编译器将转换为

-(NSString *)name;
-(void)setName:(NSString *)name;

然后对于访问器方法的定义有两种方法。

  1. 手动 - 在实现文件(.m)中使用dynamic,然后通过执行此操作来定义访问器方法,您将不会收到任何警告。

  2. 让编译器完成这项工作 - 这可以通过合成属性来完成,例如synthesize name;。所以现在编译器会为你生成访问器方法的定义。

  3. 希望它有所帮助;)

答案 2 :(得分:2)

我知道这个主题在这里已经被打败了......但是有些人似乎专注于技术细节,而我想提到一些与大图片有关的东西......

将物业视为一流的伊娃。属性和ivars都可以为对象的属性建模......但是如果你继续将ivar设置为属性,那么ivar会受到特别关注。基本上,如果你觉得它需要getter / setter方法,你应该将属性作为属性(而不是ivar)。点符号使代码非常易读。这可能有助于决定何时将变量声明为属性,而不是简单地使用常规的ivar。

答案 3 :(得分:1)

目标c中的属性实际上是setter和getter方法,可以从外部访问类中的属性。所以当你声明例如

@interface example:NSObject{
    NSString *variable;
}
@property(readwrite, assign) NSString *variable;
@end

@implementation
@synthesize variable;
@end

你实际上是在声明方法

-(NSString *)getVariable;
-(void)setVariable(NSString *)value;

然后您可以使用点表示法和属性名称来访问,例如

instance.variable = something;
something = instance.variable;

答案 4 :(得分:1)

实例变量属性之间的主要区别在于属性,编译器将自动生成getter / setter方法对。例如:

@property (nonatomic) int value;

将生成:

-(void)setValue:(int)i
{
    value = i;
}
-(int)value
{
    return self->value;
}

给出@synthesize d。

如果你在Objective-C 1.0上抄书,你会发现这个功能不可用。这是2.0中的一项新功能,也称为虚线语法。它的介绍主要是因为复杂的getter / setter语法。

此功能的好处是,即使您让编译器自动为您声明了该对,您仍然可以设法覆盖它。例如,您仍然可以将-(void)setValue:(int)i声明为您的类的方法,并覆盖该行为。这在验证方案中很有用,例如您希望对value的范围设置限制。

就Java而言,Objective-C实际上有@public实例变量语法,但不习惯使用它。它类似于Java通过getter / setter保护私有变量的概念。但它的主要目标-c是覆盖getter / setter并最小化语法。

现在这只是一个预览版,如果您想了解更多内容,请参阅http://cocoacast.com/?q=node/103或一些Objective-c 2.0书籍。

答案 5 :(得分:1)

好吧,也许不清楚属性不需要实例变量。 您可以基于对实例变量的任何计算或范围中的任何其他变量来定义只读属性。这里的问题是你必须手动编写getter代码。

@interface person:NSObject{
    NSDate *birthDate;
}
@property(readonly) int age;
@end

@implementation

-(int) age{
 // return calculated age based on birthDate and today;
}
@end

属性的名称不必与实例变量相同。

@synthesize myProperty = myVar;

答案 6 :(得分:0)

我找到了这个惊人的线程,清楚地解释了每个属性和所有关于属性的内容。

http://www.iphonedevsdk.com/forum/iphone-sdk-tutorials/7295-getters-setters-properties-newbie.html

谢谢大家的回复。