Синтезированное свойство протокола не видящего суперкласса 'ivar - PullRequest
1 голос
/ 03 июня 2010

У меня есть ситуация, когда мой подкласс не видит переменную экземпляра суперкласса x. Очевидно, что ivar по умолчанию @protected, так почему я получаю ошибку компилятора "x undeclared"?

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

EDIT: hitSize - это свойство протокола, которому соответствует мой подкласс. Проблема заключалась в том, что у меня был hitSize @synthesize d, который был виновником. Тогда возникает вопрос: почему синтезированный геттер не видит ивар?

РЕДАКТИРОВАТЬ: Теперь, когда я обнаружил проблему, я редактировал вопрос, чтобы спросить, почему это ошибка.

Ответы [ 4 ]

3 голосов
/ 03 июня 2010

Ответы Джоанны верны (хотя синтез ивара не срабатывает на 32-битной Mac OS X).

Причина, однако, заключается в том, что разрешение подклассу синтезировать доступ к внутреннему состоянию суперкласса явно нарушило бы инкапсуляцию. Было принято решение явно не допускать эту конкретную модель во всех случаях, даже в рамках одной структуры.

Если суперкласс предоставляет хранилище для чего-либо, он должен обеспечивать контроль доступа и инкапсулировать управление указанной памятью. Если подклассу необходимо настроить доступ, сделайте это с осторожностью, переопределив метод получения / установки [и, предпочтительно, вызов супер, чтобы фактически получить / установить значение].

2 голосов
/ 03 июня 2010

Вы также можете использовать явные атрибуты getter / setter для доступа, даже к @private ivars базового класса:


@interface Base : NSObject
{
  @protected
    int intVar;
}

@end

@interface Derived : Base
{
}

@property (assign, getter = intVar, setter = intVar) int aVar;

@end

1 голос
/ 03 июня 2010

Спасибо, 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
1 голос
/ 03 июня 2010

Синтезированные свойства не только синтезируют геттеры и сеттеры, они также синтезируют ивар, если он не объявлен.

Вам необходимо написать явные методы доступа в подклассе и получить доступ к @ защищенному ivar через синтаксис self-> myIvar.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...