Приведение экземпляра класса к протоколу @в 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
класса.
2 ответа:
правильный способ сделать это тут:
if ([self.myViewController conformsToProtocol:@protocol(MyProtocol)]) { UIViewController <MyProtocol> *vc = (UIViewController <MyProtocol> *) self.myViewController; [vc protocolMethod]; }
The
UIViewController <MyProtocol> *
type-cast переводится как "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
) вместе с протоколом, который вы хотите.