合成实例变量生成时会被设置为私有的而不是受保护的吗?

4

最近在iOS中的运行时,我们可以定义属性来生成实例变量的访问器。据我所知,不必声明使用的实例变量,因为它会自动为我们完成。

例如,如果我写:

@interface MyFirstClass
@property (readonly, nonatomic) int size; 
@end

在.m文件中。
@implementation MyFirstClass
@synthesize size;
@end

那么一个名为“size”的实例变量将被添加给我,并且将实现一个名为“-(int)size”的方法。

问题是,当我创建第二个类MySecondClass作为MyFirstClass的子类时,似乎无法在这个子类中访问实例变量size:

@interface MySecondClass : MyFirstClass
@end

@implementation MySecondClass
- (id)init {
    if (self = [super init]) {
        size = 10;  // this yields and error
    }
    return self;
}
@end

自动生成的实例变量是私有的吗?是否有可能将它们设置为受保护的,以便我可以在子类中访问它们? 我知道有可能自己声明实例变量,但我只是想知道... 像这样的超类可以工作:(是因为明确声明为protected吗?)
@interface MyFirstClass {
    int size;  // defined expressly and used as @protected
}
@property (readonly, nonatomic) int size;
@end

感谢您的帮助! 尼古拉斯。

2个回答

3
任何未在主接口中声明的实例变量都会自动变为私有,无法覆盖。如果您在实现过程中尝试使用作用域修饰符定义实例变量,则会出现规范不一致的错误。
这是因为通常每个实现文件只有一个类,这意味着编译器在编译其他类时不知道实例变量。如果在同一文件中有多个类,则编译器可以知道它,但您仍然不允许覆盖作用域。在这种情况下可能的原因是为了保持一致性,或者只是为了让编译器不必在那么多地方查找实例变量。

好的,这意味着我必须在接口中声明变量,才能直接在子类中访问它,对吗? 自动生成的实例变量实际上是私有的。 - Nicolas B.
没错,这是编译器查找超类实例变量的唯一位置。 - ughoavgfhw

0

使用:

self.size = 10;

这将映射到setSize方法。


1
我认为这不会起作用,因为我没有请求setter,我是对的吗?谢谢。 - Nicolas B.
setter 只有在您想要更改默认 setter 以使用另一个名称或另一个变量名称时才需要。试试看! - Rayfleck
抱歉,我不明白。我不想在这里使用任何公共的setter,这应该是一个受保护的变量。你能澄清一下吗? - Nicolas B.
问题并不在于setter,而是我为什么不能直接使用名称(直接访问)在子类中访问变量。 - Nicolas B.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接