Is there a difference between an “instance variable” and a “property” in Objective-c?
目标C中的"实例变量"和"属性"之间有区别吗?
我对此不太确定。我认为"属性"是一个具有访问器方法的实例变量,但我可能认为是错误的。
属性是一个更抽象的概念。实例变量实际上只是一个存储槽,就像结构中的槽。通常其他对象不应该直接访问它们。另一方面,属性是可以访问的对象属性(听起来很模糊,应该是这样)。通常一个属性会返回或设置一个实例变量,但它可以使用多个或一个都不使用的数据。例如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | @interface Person : NSObject { NSString *name; } @property(copy) NSString *name; @property(copy) NSString *firstName; @property(copy) NSString *lastName; @end @implementation Person @synthesize name; - (NSString *)firstName { [[name componentsSeparatedByString:@""] objectAtIndex:0]; } - (NSString *)lastName { [[name componentsSeparatedByString:@""] lastObject]; } - (NSString *)setFirstName:(NSString *)newName { NSArray *nameArray = [name componentsSeparatedByString:@""]; NSArray *newNameArray [[NSArray arrayWithObjects:newName, nil] arrayByAddingObjectsFromArray:[nameArray subarrayWithRange:NSMakeRange(1, [nameArray size]-1)]]; self.name = [newNameArray componentsJoinedByString:@""]; } - (NSString *)setLastName:(NSString *)newName { NSArray *nameArray = [name componentsSeparatedByString:@""]; NSArray *newNameArray [[nameArray subarrayWithRange:NSMakeRange(0, [nameArray size]-2)] arrayByAddingObjectsFromArray:[NSArray arrayWithObjects:newName, nil]]; self.name = [newNameArray componentsJoinedByString:@""]; } @end |
(注:上述代码是错误的,因为它假定名称已经存在,并且至少有两个组件(例如,"bill gates"而不仅仅是"gates")。我觉得修改这些假设会使代码的实际意义不那么清晰,所以我只是在这里指出,所以没有人会无意中重复这些错误。)
属性是实现某个值的getter/setter的一种友好方法,它具有其他有用的特性和语法。属性可以由实例变量支持,但您也可以定义getter/setter来执行一些更动态的操作,例如,您可以在动态创建结果的字符串上定义小写属性,而不是返回某个成员变量的值。
下面是一个例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | // === In your .h === @interface MyObject { NSString *propertyName; } // ... @property (nonatomic, retain) NSString *propertyName; // === In your .m @implementation === @synthesize propertyName /* = otherVarName */; |
1 2 | myObject.propertyName = @"Hello World!"; NSLog("Value: %@", myObject.propertyName); |
当您分配或从
除了
在您的
有3个属性值控制任何
第二个是
第三个是
最后,还可以使用
我使用接口部分的属性-其中对象与其他对象接口实例变量是您在类中需要的东西——除了您应该看到和操作它们之外,没有人需要它。
默认情况下,读写属性将由实例变量支持,编译器将再次自动合成该实例变量。
实例变量是一个存在的变量,在对象的生命周期中保存其值。用于实例变量的内存在对象首次创建时分配(通过alloc),在对象释放时释放。
除非您另外指定,否则合成实例变量与属性具有相同的名称,但带有下划线前缀。例如,对于名为firstname的属性,合成的实例变量将被称为_firstname。
以前人们公开使用财产,私人使用IVARs,但从几年前开始,您还可以在
然而,在苹果公司最近的代码中,ivar不再使用。我想是因为它更像是