Передача экземпляра класса в @protocol в Objective-C
У меня есть объект (UIViewController), который может или не может соответствовать протоколу, который я определил.
Я знаю, что могу определить, соответствует ли объект протоколу, затем безопасно вызовите метод:
if([self.myViewController conformsToProtocol:@protocol(MyProtocol)]) {
[self.myViewController protocolMethod]; // <-- warning here
}
Однако XCode показывает предупреждение:
warning 'UIViewController' may not respond to '-protocolMethod'
Какой правильный способ предотвратить это предупреждение? Кажется, я не могу отличить self.myViewController
как класс MyProtocol
.
Ответы
Ответ 1
Правильный способ сделать это:
if ([self.myViewController conformsToProtocol:@protocol(MyProtocol)])
{
UIViewController <MyProtocol> *vc = (UIViewController <MyProtocol> *) self.myViewController;
[vc protocolMethod];
}
UIViewController <MyProtocol> *
type-cast переводит на "vc - объект UIViewController, который соответствует MyProtocol", тогда как использование id <MyProtocol>
переводит на "vc - объект неизвестного класса, который соответствует MyProtocol".
Таким образом, компилятор даст вам правильную проверку типов на vc
- компилятор даст вам предупреждение только в том случае, если вызывается какой-либо метод, который не объявлен ни на UIViewController
, либо <MyProtocol>
. id
следует использовать только в ситуации, если вы не знаете класс/тип объекта, который выполняется.
Ответ 2
Вы можете сделать это следующим образом:
if([self.myViewController conformsToProtocol:@protocol(MyProtocol)])
{
id<MyProtocol> p = (id<MyProtocol>)self.myViewController;
[p protocolMethod];
}
Это тоже меня бросило. В Objective-C протокол не является самим типом, поэтому вам нужно указать id
(или какой-либо другой тип, например NSObject
), а также тот протокол, который вы хотите.