Приведите экземпляр класса к @protocol в Objective-C

StackOverflow https://stackoverflow.com/questions/617616

  •  03-07-2019
  •  | 
  •  

Вопрос

У меня есть объект (UIViewController), который может соответствовать или не соответствовать протоколу, который я определил.

Я знаю, что могу определить, соответствует ли объект протоколу, а затем безопасно вызвать метод:

if([self.myViewController conformsToProtocol:@protocol(MyProtocol)]) {
    [self.myViewController protocolMethod]; // <-- warning here
}

Тем не менее, XCode показывает предупреждение:

warning 'UIViewController' may not respond to '-protocolMethod'

Как правильно предотвратить это предупреждение? Я не могу назвать self.myViewController классом MyProtocol.

Это было полезно?

Решение

Правильный способ сделать это - сделать:

if ([self.myViewController conformsToProtocol:@protocol(MyProtocol)])
{
        UIViewController <MyProtocol> *vc = (UIViewController <MyProtocol> *) self.myViewController;
        [vc protocolMethod];
}

Приведение типов UIViewController <MyProtocol> * переводится в " vc является объектом UIViewController, который соответствует MyProtocol " в то время как использование id <MyProtocol> переводит в " vc является объектом неизвестный класс, соответствующий MyProtocol ".

Таким образом, компилятор даст вам правильную проверку типа на vc - компилятор выдаст вам предупреждение только в том случае, если вызван какой-либо метод, который не объявлен ни в UIViewController, ни в <MyProtocol>. id следует использовать только в том случае, если вы не знаете класс / тип объекта, который приводится.

Другие советы

Вы можете разыграть его так:

if([self.myViewController conformsToProtocol:@protocol(MyProtocol)])
{
    id<MyProtocol> p = (id<MyProtocol>)self.myViewController;
    [p protocolMethod];
}

Это меня тоже немного отбросило. В Objective-C протокол не является самим типом, поэтому вам нужно указать id (или другой тип, например NSObject) вместе с нужным протоколом.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top