Pergunta

Eu tenho um objeto (a UIViewController), que pode ou não estar de acordo com um protocolo que eu definido.

Eu sei que posso determinar se o objeto está em conformidade com o protocolo, em seguida, chamar com segurança o método:

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

No entanto, XCode exibe um aviso:

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

O que é o caminho certo para evitar este aviso? Eu não consigo self.myViewController elenco como uma classe MyProtocol.

Foi útil?

Solução

A maneira correta de fazer isso é fazer:

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

O UIViewController <MyProtocol> * tipo elenco se traduz em "vc é um objeto UIViewController em conformidade com MyProtocol", enquanto usando id <MyProtocol> se traduz em "vc é um objeto de uma classe desconhecida em conformidade com MyProtocol".

Desta forma, o compilador irá dar-lhe a verificação de tipo adequada sobre vc - o compilador só vai te dar um aviso se qualquer método que não é declarado em ambos UIViewController ou <MyProtocol> é chamado. id só deve ser usado na situação, se você não sabe a classe / tipo do objeto sendo elenco.

Outras dicas

Você pode lançá-lo como este:

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

Esta me jogou para um pouco, também. Em Objective-C, o protocolo não é o próprio tipo, então você precisa especificar id (ou algum outro tipo, como NSObject), juntamente com o protocolo que você deseja.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top