ti-enxame.com

Erro Xcode: Nenhum método de instância conhecido para seletor

Preciso de ajuda para depurar minha aula. Eu estou recebendo um erro tão bizarro que eu não consegui encontrar nada parecido, então eu só vou colocar a maior parte do meu código.

//Tab.h
#import <UIKit/UIKit.h>
@class Tab;
@protocol TabDelegateDataSource <NSObject>
@required
-(void)removeTab:(Tab *)tab;
@end

@interface Tab : UIView
{
     id <TabDelegateDataSource> __strong _delegate;
}

@property(strong) id <TabDelegateDataSource> delegate;

-(void)removeTab;

@end

//  Tab.m
#import "Tab.h"
@implementation Tab
@synthesize delegate = _delegate;
-(void)removeTab
{
    [self.delegate removeTab:self];//Error here saying: No known instance method for selector 'removeTab:'  
}

@end
15
Jordan Medlock

Eu acho que foi um problema estúpido com o Xcode eu reiniciei o aplicativo algumas vezes e acabou malhando.

6
Jordan Medlock

Agora posso recriar e corrigir esse erro à vontade.

Certifique-se de que o cabeçalho .h, onde isso é definido ...

@protocol TabDelegateDataSource <NSObject>
-(void)removeTab:(Tab *)tab;
@end

... está incluído onde quer que você planeje usar o delegado, e. em algum lugar no topo da fonte .m que inclui isso:

[self.delegate removeTab:self]

Se o compilador tiver visto apenas um definição para frente de tabdelegatedatasource como este:

@protocol TabDelegateDataSource;

Você receberá o erro:

error: no known instance method for selector 'removeTab:'

e não o erro de definição mais esperada

15
dpjanes

Você deve sempre verificar seu delegado desta forma, antes de ligar para um método, mesmo com os métodos de protocolo necessários:

if( self.delegate != nil && [ self.delegate respondsToSelector: @selector( removeTab: ) ]
{
    /* Call delegate method... */
}

Fazer isso mesmo para os métodos necessários adiciona uma segurança extra, pois esta verificação é feita no tempo de execução.
[.____] Alguém pode ignorar ou desativar os avisos do compilador, ou enganar o compilador com elenco.

Por exemplo:

UILabel * label        = [ [ UILabel alloc ] initWithFrame: CGRectZero ];
someTableView.delegate = ( id < UITableViewDelegate > )label;

Além disso, você pode querer usar performSelector para a chamada real do método:

[ self.delegate performSelector: @selector( removeTab: ) withObject: self ];
4
Macmade

Meu problema foi que eu perdi para declarar <NSObject> no protocolo.

@protocol CustomProtocol <NSObject>
- (void)doSomethingWithSize:(CGSize)size;
@end
2
atulkhatri

Certifique-se de que você não declarou incorretamente a propriedade delegada na interface (provavelmente copiando e colando de outro arquivo). Por exemplo:

@protocol SomeDelegate

...

@end

@interface SomeClass

...

@property (nonatomic, retain) id<DifferentDelegate>delegate; 


@end

A linha acima causará o "nenhum método de instância conhecido para selector ..." por causa da incompatibilidade com o protocolo indendido, provavelmente um erro de cópia e colar. Além disso, é provável que seja a referência correta a partir de uma classe diferente, onde ela realmente pertence, longe dessa linha de código, dificultando a localização.

Corrija o acima declarando sua propriedade com o protocolo pretendido:

@property (nonatomic, retain) id<SomeDelegate>delegate;
2
Noah Dyer

Alguém pode ser necessário,

SEL selector = NSSelectorFromString(@"removeTab");

if([self.delegate respondsToSelector:selector]) {
    objc_msgSend(self.delegate, selector);
}

Nota: Não esqueça isso, #import <objc/message.h>

1
Arun

Tente renomear o delegate para outros como delegateForTab.

Sua classe Tab está subclasse UIView, então self.delegate 's self classe também é uma subclasse do UIView. UIView pode ter seu próprio delegado (herda do Uiresponder, e profundo do NSOBJECT), e não tem o método -(void)removeTab. Apenas meu palpite pessoal.
[.____] Minha solução é renomear (não encontre a resposta se ele pode ser subclassado ainda).

Sugestão para usar Delegate: Você deve implementar o protocol e use o delegate em outros controladores de visualização, não na mesma classe que você o declara. :)

1
Kjuly

Eu importo meu appdelegate.h e o erro resolvido ...

0
Gaurav

Este erro não é um erro do compilador, não é? Porque não tenho erros de compilador com seu código aqui.

Então, se este é um erro de tempo de execução, você declarou <TabDelegateDataSource> em suas classes delegadas como esta:

@interface SomeClass : UIView <TabDelegateDataSource>

Se você o fez, o compilador deveria estar avisando se o seu método de instância não puder ser encontrado.

Ou talvez você também deve postar o código da sua classe delegada para mais informações.

P.S. O delegado não deve ser __strong. É melhor você usar __unsafe_unretained em vez de.

0
xuzhe