合成的实例变量是不是生成为私有而不是受保护?

Posted

技术标签:

【中文标题】合成的实例变量是不是生成为私有而不是受保护?【英文标题】:Are synthesized instance variables generated as private instead of protected?合成的实例变量是否生成为私有而不是受保护? 【发布时间】:2012-03-03 22:10:07 【问题描述】:

由于最近在 ios 中运行时,我们能够定义将为实例变量生成访问器的属性。据我了解,声明使用的实例变量不是强制性的,因为它会自动为我们完成。

例如,如果我写:

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

在.m中

@implementation MyFirstClass
@synthesize size;
@end

然后会为我添加一个名为“size”的实例变量,并实现一个名为“-(int)size”的方法。

问题是当我创建第二个类 MySecondClass 时,它是 MyFirstClass 的子类,我似乎无法访问该子类中的实例变量大小:

@interface MySecondClass : MyFirstClass
@end

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

@end

自动创建的实例变量是私有的吗?是否有可能将它们设置为受保护,以便我可以在子类中访问它们? 我知道可以自己声明实例变量,但我只是想知道......

这样的超类可以工作:(是因为它被明确声明为受保护的吗?)

@interface MyFirstClass 
    int size;  // defined expressly and used as @protected

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

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

【问题讨论】:

【参考方案1】:

用途:

self.size = 10;

这将映射到 setSize 方法。

【讨论】:

我认为这行不通,因为我没有问任何二传手,我是对的吗?谢谢。 setter 仅在您想更改默认设置器以使用其他名称或其他变量名称时使用。试试看! 对不起,我不明白。我不想要任何公共设置器,这应该是一个受保护的变量。你能澄清一下吗? 这里的问题不是setter,而是为什么我不能只用名字访问子类中的变量(直接访问)。【参考方案2】:

任何未在主界面中声明的实例变量都是自动私有的,并且不能被覆盖。如果在实现中定义实例变量的时候尝试使用作用域修饰符,会报规范不一致的错误。

这样做的原因是每个实现文件通常只有一个类,这意味着编译器在编译其他类时不知道实例变量。如果您在同一个文件中有多个类,编译器可以知道它,但仍然不允许您覆盖范围。在这种情况下,可能的原因可能是为了保持一致性,或者只是为了让编译器不必在很多地方查找实例变量。

【讨论】:

好的,这意味着我必须在接口中声明变量才能在子类中直接访问它,对吧?自动创建的实例变量实际上是私有的。 对。这是编译器查找超类实例变量的唯一位置。

以上是关于合成的实例变量是不是生成为私有而不是受保护?的主要内容,如果未能解决你的问题,请参考以下文章

为啥这里的 String 构造函数应该被保护而不是私有?

将受保护的 Objective-C 实例变量公开给子类

对字段和方法使用私有而不是受保护的原因

关于 Objective-C 中的私有实例变量

将属性置于受保护/私有的任何性能原因?

Twig 访问受保护/私有模型变量