什么是Objective-C中的默认变量访问权限类型?

时间:2014-02-06 09:58:51

标签: objective-c

例如,我有一些A类。然后我从A继承了另一个类。

@interface A : NSObject
{
    int _nonHiddenProp;

    @private 
        int _hiddenProp;
}
@property (nonatomic, assign) int property;
@property (nonatomic, assign) int nonHiddenProp;
@property (nonatomic, assign) int hiddenProp;
@end

@implementation A
- (id)init
{
    if (self = [super init])
    {
        _property = 1000;
    }

    return self;
}
@end


@interface B : A

@end

@implementation TestCapabilitiesChild

- (id)init
{
    if (self = [super init])
    {
        _nonHiddenProp = 1000;
        //I cannot call _property and _hiddenProperty
    }

    return self;
}
@end

可是:

A *a = [[[A alloc] init] autorelease];
B *b = [[[B alloc] init] autorelease];
NSLog(@"BClassProperties %d %d %d", b.nonHiddenProp, b.property, b.hiddenProp);

显示:BClassProperties 1000 1000 0

为什么呢?如果我不能在B的init中调用变量_property它仍然是1000?

2 个答案:

答案 0 :(得分:0)

您已明确声明了两个实例变量_nonHiddenProp_hiddenProp,其中_nonHiddenProp可以看到子类,而_hiddenProp只能看到它所在的类。您有还声明了三个属性:propertynonHiddenProphiddenProp

首先要注意的是属性不是变量。属性和实例变量是不同的东西。属性实际上是一对存取方法,一个用于获取其值,另一个用于设置其值(对于只读属性,可以省略setter)。请注意,“它的值”是指属性的值而不是任何特定实例变量的值。我之前可能已经提到了这个,但是属性和实例变量不是同一个东西

由于属性实际上是一对方法,属性的可见性规则与方法相同,即“所有方法都是公共的”,因此所有属性也是公共的。

如果您没有为属性的两个访问器提供实现,并且您没有显式合成该属性,则编译器将自动提供实现。这是通过:

  • 首先发明一个实例变量名称,该名称与属性名称相同,但前面带有下划线。
  • 如果实例变量尚不存在,则声明具有私有可见性的实例变量。
  • 创建getter和setter以在获取/设置属性时获取/设置实例变量。

您无法在子类中设置实例变量_property,因为子类没有实例变量的可见性。 NSLog的工作原理是因为它使用的是属性,而不是实例变量。

答案 1 :(得分:-1)

你为实例变量声明了一个属性...这意味着,一个setter和getter是同步的,这是方法...在Objective-C中所有方法都是公共的(通过你可以“隐藏”它们,或者编译器/ IDE可能会阻止您编译)

但实际上并且在运行时期间,没有什么能阻止您在该类上发送消息(调用方法)