Указатель Objective C для классификации, который реализует протокол

У меня есть три класса, которые реализуют тот же протокол и имеют тот же родительский класс, который не реализует протокол. Обычно у меня был бы протокол как чистые виртуальные функции в родительском классе, но я не мог найти Objective C способом сделать это.

Я хочу использовать полиморфизм на этих подклассах путем объявления, что чистые виртуальные функции в суперклассе затем сделали, чтобы дети реализовали те функции. Однако единственный Objective C путем, который я нашел, чтобы сделать, это должно иметь каждого ребенка, явно решают реализовать протокол, когда я делаю это этот способ, которым суперкласс не знает, что дети реализуют тот протокол, таким образом, будут предупреждения времени компиляции повсеместно.

Некоторый псевдокод, если это не имело смысла:

@interface superclass: NSObject
{}

@interface child1: superclass<MyProtocol>
{}

@interface child2: superclass<MyProtocol>
{}

Потребитель этих классов:

@class child1
@class child2
@class superclass

@interface SomeViewController: UIViewController
{
    child1 *oneView;
    child2 *otherView;
    superclass *currentView;
}

-(void) someMethod
{
    [currentView protocolFunction];
}

Единственным хорошим путем я нашел, чтобы сделать, чистые виртуальные функции в Objective C являются взломом путем помещения [self doesNotRecognizeSelector:_cmd]; в родительском классе, но это не идеально, так как это вызовет ошибки периода выполнения, а не время компиляции.

7
задан Winder 19 April 2010 в 19:32
поделиться

4 ответа

Мне удалось заставить компилятор правильно предупреждать меня, сделав свойство суперкласса * currentView выглядеть следующим образом:

@property (nonatomic, retain) superclass<MyProtocol> *currentView;
5
ответ дан 6 December 2019 в 09:18
поделиться

Лично я бы реализовал протокол в суперклассе, но реализовал бы такие методы:

- (id) myProtocolMethod {
  NSAssert(NO, [NSString stringWithFormat:@"-[%@ %@] must be overridden", NSStringFromClass([self class]), NSStringFromSelector(_cmd)]);
  return nil;
}

Таким образом, если вы когда-нибудь забудете переопределить метод в конкретном подклассе, это должно быть сразу очевидно.

1
ответ дан 6 December 2019 в 09:18
поделиться

В таких ситуациях разработчики Objective-C обычно используют динамическую проверку, а не проверку во время компиляции, потому что язык и фреймворки так хорошо ее поддерживают. Так, например, вы можете написать свой метод так:

- (void)someMethod
{
    // See if the object in currentView conforms to MyProtocol
    //
    if ([currentView conformsToProtocol:@protocol(MyProtocol)])
    {
        // Cast currentView to the protocol, since we checked to make
        // sure it conforms to it. This keeps the compiler happy.
        //
        [(SuperClass<MyProtocol> *) currentView protocolMethod];
    }
}
11
ответ дан 6 December 2019 в 09:18
поделиться

В качестве альтернативы вы можете использовать следующий

if ([unknownObject conformsToProtocol:@protocol(MyProtocol)])
   [unknownObject performSelector:@selector(methodInProtocol)];

вместо следующего, если вы просто хотите подавить предупреждение.

if ([unknownObject conformsToProtocol:@protocol(MyProtocol)])
   [unknownObject methodInProtocol];  // will cause warning

performSelector: будет работать, только если количество аргументов равно нулю или единице. Более гибкие вызовы могут быть достигнуты с помощью NSInvocation.

3
ответ дан 6 December 2019 в 09:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: