代码之家  ›  专栏  ›  技术社区  ›  Morrowless

一个协议的合成属性,看不到超类的ivar

  •  1
  • Morrowless  · 技术社区  · 15 年前

    在这种情况下,我的子类没有看到超类的实例变量 x . 伊瓦尔显然是 @protected 默认情况下,为什么我会得到一个编译器错误“X未声明”?

    - (CGSize)hitSize
    {
        // Compiler error
        return size;
    }
    

    编辑:hitsize是我的子类符合的协议的属性。问题是我有hitsize @synthesize 这是罪魁祸首。那么问题是,为什么合成吸气剂看不到IVAR?

    编辑:现在我发现了这个问题,我编辑了这个问题,问为什么这是一个错误。

    4 回复  |  直到 15 年前
        1
  •  3
  •   bbum    15 年前

    乔安娜的答案都是正确的(尽管Ivar合成并没有在32位Mac OS X上发挥作用)。

    但是,原因是允许子类合成对超类内部状态的访问会明显破坏封装。做出的决定是,在所有情况下,即使在单一框架内,也明确不允许这种特定模式。

    如果一个超类为某物提供存储,它应该提供访问控制并封装所述内存的管理。如果一个子类需要定制访问,那么通过重写getter/setter(最好是调用super来实际获取/设置值),小心地这样做。

        2
  •  2
  •   Joanna Carter    15 年前

    您还可以使用显式getter/setter属性来访问,甚至是基类的@private ivar:

    @interface Base : NSObject
    {
      @protected
        int intVar;
    }
    
    @end
    
    @interface Derived : Base
    {
    }
    
    @property (assign, getter = intVar, setter = intVar) int aVar;
    
    @end
    
    
        3
  •  1
  •   Joanna Carter    15 年前

    合成属性不仅合成getter和setter,如果没有声明,它们还合成ivar。

    您需要在子类中编写显式访问器,并通过self->myivar语法访问@protected ivar。

        4
  •  1
  •   Joanna Carter    15 年前

    感谢bbum对我的回答进行了详细的阐述。

    关于您的第二个答复,您当然是对的,在这种情况下,您可以使用类扩展来隐藏基类上的属性,如下所示:

    // Example.h
    @interface Base : NSObject
    {
      @private
        int intVar;
    }
    
    @end
    
    @interface Derived : Base
    {
    }
    
    @property (assign) int aVar;
    
    @end
    
    // Example.m
    @interface Base ()
    
    @property (assign) int intVar;
    
    @end
    
    @implementation Base
    
    @synthesize intVar;
    
    @end;
    
    @implementation Derived
    
    - (int) aVar
    {
      return self.intVar;
    }
    
    - (void) setAVar:(int)value
    {
      self.intVar = value;
    }
    
    @end