我对实例变量和属性感到非常困惑。我已经阅读了许多关于此的帖子,但我仍然不清楚。我来自 JAVA 背景,我从客观 C 文档中推断出一个属性类似于 JAVA BEAN CLASS(具有实例变量的 getter 和 setter)。属性可以通过其 getter 和 setter 方法从其他类访问,而实例变量是私有的,不能从其他类访问。
我在这个方向上的想法是对的吗?
我对实例变量和属性感到非常困惑。我已经阅读了许多关于此的帖子,但我仍然不清楚。我来自 JAVA 背景,我从客观 C 文档中推断出一个属性类似于 JAVA BEAN CLASS(具有实例变量的 getter 和 setter)。属性可以通过其 getter 和 setter 方法从其他类访问,而实例变量是私有的,不能从其他类访问。
我在这个方向上的想法是对的吗?
与Java的并行非常好。唯一的区别是,Objective C 提供了一种访问属性的方法,就像它是一个变量一样,而 Java 没有。另一个区别是,在 Objective C 中您可以合成属性,而在 Java 中您需要手动编写 getter 和 setter。
属性是 getter 方法或一对 getter 和 setter 方法的“语法糖”。属性通常(但不总是)由实例变量支持,但它们可以以任何可以实现无参数实例方法的方式实现。
好的,实例变量和属性相距甚远。实例变量是对象的状态,属性是该状态(实例变量)的 assecor 方法(getter/setter)。
因此,每当您在头文件中创建属性时。编译器将这些属性转换为访问器方法。假设您声明了属性-@property(nonatomic, assign, readwrite) NSString *name;
因此编译器会将其转换为
-(NSString *)name;
-(void)setName:(NSString *)name;
然后对于访问器方法的定义有两种方法。
手动 - 在实现文件(.m)中使用动态,然后通过这样做给出访问器方法的定义,您不会收到任何警告。
让编译器完成这项工作 - 这可以通过综合属性来完成,例如synthesize name;
. 所以现在编译器将为您生成访问器方法的定义。
希望能帮助到你 ;)
我知道这个主题在这里已经被打死了......但有些人似乎专注于技术细节,而我想提到一些大图的东西......
将属性视为一流的 ivars。属性和 ivars 都可以对对象的属性进行建模……但是如果您继续将其设置为属性,则 ivar 会受到特别关注。基本上,如果您觉得它需要 getter / setter 方法,则应该将属性作为属性(而不是 ivar)。点符号使代码非常易读。这可能有助于决定何时将变量声明为属性,而不是简单地使用常规 ivar。
目标 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;
实例变量和属性的主要区别在于,对于属性,编译器会自动生成一个 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 书籍。
好吧,也许不清楚属性是否需要实例变量。您可以根据对实例变量或范围内任何其他变量的任何计算来定义只读属性。这里的问题是您必须手动编写 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;
我发现了这个惊人的线程,它清楚地解释了关于属性的每一个细节。
http://www.iphonedevsdk.com/forum/iphone-sdk-tutorials/7295-getters-setters-properties-newbie.html
谢谢大家的回复。