Определение условий в протоколах - PullRequest
0 голосов
/ 28 апреля 2011

У меня есть такой протокол:

@protocol ProfileSubObjects <NSObject, NSCoding>
@required
- (BOOL) hasGraph;

@optional
- (NSArray *) xGraphValues;
- (NSArray *) yGraphValues;

Я хочу сделать обязательными эти два дополнительных метода, если hasGraph равен YES. Возможно ли это?

Ответы [ 3 ]

1 голос
/ 28 апреля 2011

Нет, это невозможно. По крайней мере, не так. Однако есть более глубокая проблема. Вопрос предполагает рассмотрение проверки компиляции и времени выполнения и ориентации объекта.

Пометка чего-либо как @optional или @required означает, что вы хотите выполнить проверку во время компиляции, чтобы эти объекты выполняли протокол протокола о предоставлении реализаций - или не в случае @optional - этих методов.

Поэтому нет никакой причины, чтобы проверка времени компиляции зависела от значения переменной времени выполнения, в данном случае hasGraph.

Лучшим подходом было бы использовать проверку сообщений RespondsToSelector. В качестве альтернативы у вас может быть подкласс, который имеет график и предоставляет значения графиков x и y.

1 голос
/ 28 апреля 2011

Нет.Методы либо требуются протоколом, либо нет.Во-первых, значение -hasGraph не известно во время компиляции.Так как это метод экземпляра, а не метод класса, он даже не известен во время выполнения, пока вы не создадите конкретный объект.Кроме того, объект может сообщать разные значения для -hasGraph в разное время.

Лучше всего здесь просто документально подтвердить тот факт, что если -hasGraph возвращает YES, ожидается, что -xGraphValues ​​и -yGraphValues ​​будутреализованы.Вы можете применить это, вызвав исключение, или вы могли бы изящно потерпеть неудачу и просто не рисовать какие-либо данные, если эти методы не реализованы.Используйте -respondsToSelector: метод, чтобы проверить, реализован ли метод перед его вызовом.

0 голосов
/ 28 апреля 2011

Это невозможно; результат hasGraph будет известен только во время выполнения, тогда как обязательные / необязательные части протокола используются компилятором для проверки чего-либо во время компиляции.

То, что вы, вероятно, хотите сделать, это добавить заметку о том, что если hasGraph возвращает YES, то должны быть реализованы xGraphValues ​​и yGraphValues, что вносит небольшую неформальность в ваш официальный протокол. Вы всегда можете сделать что-то вроде:

if([object respondsToSelector:@selector(xGraphValues)] && 
   [object respondsToSelector:@selector(yGraphValues)])

Чтобы проверить во время выполнения, реализует ли объект те части протокола, которые вам нужны, чтобы иметь возможность выполнять с ним определенную операцию. Вероятно, было бы разумно поместить эти вещи в NSAssert, если вы хотите, чтобы кто-то, кто реализует несовместимый объект, мог узнать, что они сделали неправильно, в отладочной сборке.

...