我在一个类中声明了一个属性:
@property double x;
然后我创建了该类的子类,其中我声明了另外两个属性:
@property double a, b;
然后我在子类中创建了一个init方法:
-(id)initWithAValue:andBValue:
我可以使用:
_a; // same for b
[self setValue a]; // same for b
self.a; // same for b and x
现在,当我尝试使用x属性时,我只能使用[self setValue x]而我不能使用_x。为什么呢?
答案 0 :(得分:6)
您可以获取/设置属性,您无法直接访问它后面的实例变量/后备存储,即使它们属于子类,您通常也不会这样做。
_x
是实例变量或ivar。
self.x
是属性,可以通过使用@property
声明x
时创建的getter / setter方法进行访问。
当您使用@property
(以前与@synthesize
一起使用时,不再需要)时,它会自动生成getter,setter和支持ivar。 ivar本身,取决于声明的位置创建为@protected
或@private
。回答this question,虽然有点旧,但要对不同的可见性修饰符有所了解。
如果在公共.h文件中声明@property double x
,默认情况下它将是@protected
,这意味着访问器方法和ivar应该对超类和子类的实例可见,但是而不是其他外部类的实例。
如果您在类扩展中声明了相同的@property
或.m中的@implementation
块(仅展示您真正需要的内容),则默认为@private
,这意味着ivar只能由那个确切类的实例访问 - 而不是子类实例。这使得只有getter / setter方法暴露给子类。
如果选择,您可以覆盖这些默认值,但通常最好使用accessor / mutator方法&不直接与伊瓦尔斯打交道。这是设计使然,因为您想要精确控制其他对象(甚至是子类实例)如何访问/操作变量。