Pergunta

Criei um botão e adicionei uma ação para ele, mas assim que ele foi invocado, recebi este erro:

-[NSCFDictionary numberButtonClick:]: unrecognized selector sent to instance
 0x3d03ac0 2010-03-16 22:23:58.811
 Money[8056:207] *** Terminating app
 due to uncaught exception
 'NSInvalidArgumentException', reason:'*** -[NSCFDictionary numberButtonClick:]:  unrecognized selector sent to instance 0x3d03ac0'

Este é o meu código:

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
    if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
        UIButton *numberButton = [UIButton buttonWithType:UIButtonTypeCustom];        
        numberButton.frame = CGRectMake(10, 435, 46, 38);
        [numberButton setImage:[UIImage imageNamed:@"one.png"] forState:UIControlStateNormal];
        [numberButton addTarget:self action:@selector(numberButtonClick:) forControlEvents:UIControlEventTouchUpInside];
        [self.view addSubview: numberButton]; 
    }
return self;
}

-(IBAction)numberButtonClick:(id)sender{
    NSLog(@"---");
}
Foi útil?

Solução

Parece que você não é a memória gerenciando o controlador de visualização corretamente e está sendo desalocado em algum momento - o que causa o numberButtonClicked: Método a ser enviado para outro objeto que agora está ocupando a memória de que o controlador de vista estava ocupando anteriormente ...

Certifique -se de que você esteja retendo/liberando seu controlador de exibição adequadamente.

Outras dicas

Para aqueles que chegam aqui via Google como eu, o que provavelmente se refere a mais ao Xcode 4.2+/iOS 5+ a mais, com o ARC. Eu tive o mesmo erro "seletor não reconhecido enviado à instância". No meu caso, eu tinha uma ação de destino de Uutton criada para passar como o parâmetro do remetente, mas depois percebi que não precisava e removi isso no código. Então, algo como:

- (IBAction)buttonPressed:(UIButton *)sender {

Foi alterado para:

- (IBAction)buttonPressed {

O clique com o botão direito do mouse no UIBIBLETTON em questão mostrou que o evento interno de retoque estava associado ao Método dos controladores de exibição: o método. Remover isso e reatribuir ao método modificado funcionou um tratamento.

Essa foi a melhor resposta do Google para esse problema, mas eu tive uma causa/resultado diferente - pensei em adicionar meus dois centavos, caso outros tropeçam nesse problema.

Eu tive um problema semelhante esta manhã. Descobri que, se você clicar com o botão direito do mouse no item da interface do usuário, fornecendo o problema, poderá ver quais conexões foram criadas. No meu caso, eu tinha um botão conectado a duas ações. Excluí as ações do menu do clique com o botão direito do mouse e as reconectei e meu problema foi corrigido.

Portanto, certifique -se de que suas ações estejam conectadas à direita.

Ok, eu tenho que entrar aqui. O op criou dinamicamente o botão. Eu tive um problema semelhante e a resposta (depois de horas de caça) é tão simples que me deixou doente.

Ao usar:

action:@selector(xxxButtonClick:)

or (as in my case)

action:NSSelectorFromString([[NSString alloc] initWithFormat:@"%@BtnTui:", name.lowercaseString])

Se você colocar um cólon no final da corda - ele passará pelo remetente. Se você não colocar o cólon no final da corda, ele não, e o receptor receberá um erro, se esperar. É fácil perder o cólon se você estiver criando dinamicamente o nome do evento.

As opções de código do receptor são assim:

- (void)doneBtnTui:(id)sender {
  NSLog(@"Done Button - with sender");
}
 or
- (void)doneBtnTui {
  NSLog(@"Done Button - no sender");
}

Como sempre, é sempre a resposta óbvia que é perdida.

No meu caso, a função não esperava um argumento, mas o botão foi configurado para enviar um causando o erro. Para consertar isso, tive que reconstruir o manipulador de eventos.

Aqui está minha função:

enter image description here

Observe que não contém argumentos.

Aqui está uma imagem da minha configuração de botão (clique com o botão direito do mouse no botão para visualizá -lo):

enter image description here

Observe que existem 3 manipuladores de eventos.

Para corrigir isso, tive que remover cada um dos itens do evento, pois um deles estava enviando uma referência para si para a função entediante. Para remover esses itens, cliquei no ícone X ao lado do nome de cada item até que não houvesse itens mostrados.

enter image description here

Em seguida, tive que reconectar o botão ao evento. Para fazer isso, mantenha pressionado a tecla de controle e arraste uma linha do botão para a ação. Deve dizer "Conectar a ação". Nota: Eu tive que reiniciar o Xcode para que isso funcione por algum motivo; Caso contrário, ele apenas me permite inserir ações (também conhecidas como criar uma nova ação) acima ou abaixo da função.

enter image description here

Agora você deve ter um único manipulador de eventos conectado ao evento de botão que não passa argumentos:

enter image description here

Esta resposta complementa a resposta de @Leonard Challis, que você deve ler também.

Isso também pode acontecer se você não definir a "classe" da visualização no interface Builder.

No meu caso, eu estava usando o NSNotificationCenter e estava tentando usar um seletor que não levou argumentos, mas estava adicionando um cólon. Remover o cólon corrigiu o problema.

Ao usar um nome de seletor, não use um cólon à direita se não houver argumentos. Se houver um argumento, use um cólon atrás. Se houver mais de um argumento, você deve nomeá -los junto com um cólon à direita para cada argumento.

Veja a resposta de Adam Rosenfield aqui: Seletores no Objective-C?

Eu tive esse problema com um projeto SWIFT, onde estou criando os botões dinamicamente. Código do problema:

var trashBarButtonItem: UIBarButtonItem {
    return UIBarButtonItem(barButtonSystemItem: .Add, target: self, action: "newButtonClicked")
}

func newButtonClicked(barButtonItem: UIBarButtonItem) {
    NSLog("A bar button item on the default toolbar was clicked: \(barButtonItem).")
}

A solução foi adicionar um cólon completo ':' Após a ação: por exemplo

var trashBarButtonItem: UIBarButtonItem {
        return UIBarButtonItem(barButtonSystemItem: .Add, target: self, action: "newButtonClicked:")
    }

    func newButtonClicked(barButtonItem: UIBarButtonItem) {
        NSLog("A bar button item on the default toolbar was clicked: \(barButtonItem).")
    }

Exemplo completo aqui: https://developer.apple.com/library/content/samplecode/uicatalog/listings/swift_uikitcatalog_defaulttoolbarviewController_swift.html

A causa mais óbvia disso (incluída para completude) está lançando indevidamente um ponteiro e chamando um método da classe errada.

NSArray* array = [[NSArray alloc] init];
[(NSDictionary*)array objectForKey: key]; // array is not a dictionary, hence exception

Eu tive um problema semelhante, mas para mim a solução era um pouco diferente. No meu caso, usei uma categoria para estender uma classe existente (UIImage para alguns recursos de redimensionamento - veja isso como Caso você esteja interessado) e esqueça de adicionar o arquivo *.m ao destino de construção. Erro estúpido, mas nem sempre óbvio quando acontece onde olhar. Eu pensei que vale a pena compartilhar ...

Eu tive o mesmo erro e descobri o seguinte:

Quando você usa o código

[self.refreshControl addTarget:self action:@selector(yourRefreshMethod:) forControlEvents:UIControlEventValueChanged];

Você pode pensar que está procurando o seletor:

- (void)yourRefreshMethod{
    (your code here)
}

Mas na verdade está procurando o seletor:

- (void)yourRefreshMethod:(id)sender{
    (your code here)
}

Esse seletor não existe, então você recebe o acidente.

Você pode alterar o seletor para receber (ID) remetente para resolver o erro.

Mas e se você tiver outras funções que chamam a função de atualização sem fornecendo um remetente? Você precisa de uma função que funcione para ambos. Solução fácil é adicionar outra função:

- (void)yourRefreshMethodWithSender:(id)sender{
    [self yourRefreshMethod];
}

E, em seguida, modifique o código de pulldown de atualização para ligar para esse seletor:

[self.refreshControl addTarget:self action:@selector(yourRefreshMethodWithSender:) forControlEvents:UIControlEventValueChanged];

Também estou fazendo o curso de Stanford iOS em um Mac mais antigo que não pode ser atualizado para a versão mais recente do Mac OSX. Então, ainda estou construindo para o iOS 6.1, e isso resolveu o problema para mim.

Eu também tive o mesmo problema.

Eu excluí meu UIBUBILLETTN no meu storyboard e o recretei .. agora tudo funciona bem.

Isso aconteceu com o meu porque apaga acidentalmente o "@ibaction func ..." dentro do meu código de classe UIViewController, então no storyboard foi criado a saída de referência, mas em tempo de execução havia alguma função para processá -lo.

A solução foi excluir a referência de saída dentro do inspetor da propriedade e depois recriá -la arrastando com a tecla de comando para o código de classe.

Espero que ajude!

Eu acho que você deve usar o vazio, em vez do ibação no tipo de retorno. Porque você definiu um botão programaticamente.

Outra solução possível: adicione '-objc' aos seus argumentos de vinculador.

A explicação completa está aqui: Categorias Objective-C na biblioteca estática

Eu acho que a essência é: se a categoria for definida em uma biblioteca com a qual você está vinculando estaticamente, o vinculador não é inteligente o suficiente para vincular os métodos de categoria. A bandeira acima faz o link do vinculador em todas as classes e categorias objetivas, não apenas as acha Precisa com base na análise da sua fonte. (Por favor, sinta -se à vontade para sintonizar ou corrigir essa resposta. Eu sou conhecido para os idiomas vinculados, por isso estou apenas parecendo aqui).

Atualmente, estou aprendendo o desenvolvimento do iOS e passando pelo livro "Iniciante de Desenvolvimento do IOS6" da Apress. Eu estava recebendo o mesmo erro no Capítulo 10: Storyboards.

Levei dois dias para descobrir, mas descobri que acidentalmente defina a tag da célula de tabela para 1 quando não deveria. Para qualquer outra pessoa que faça este livro e receba um erro semelhante, espero que isso ajude.

Eu realmente espero que erros futuros no meu código sejam mais fáceis de encontrar! hahaha. O erro de depuração não fez nada para me empurrar na direção certa para descobrir (ou pelo menos eu sou novo demais para entender o depurador, lol).

No meu caso eu estava usando um UIWebView e passei um NSString no segundo parâmetro em vez de um NSURL.Portanto, suspeito que tipos de classe errados passados ​​para funções podem causar esse erro.

..E agora meu

Eu tinha o botão vinculado a um método que acessava o parâmetro de outro botão e funcionou muito bem, mas assim que tentei fazer algo com o próprio botão, recebi uma falha. Enquanto compilação, nenhum erro foi exibido. Solução?

Não vinculei o botão ao proprietário do arquivo. Então, se alguém aqui é tão estúpido quanto eu, tente isso :)

Mais uma solução/caixa ligeiramente diferente.

Estou usando Xamarin e MVVMcross e estava tentando ligar o UIBUBILDTON a um viewmodel. Eu tinha o UIBIBLETTON ligado a uma saída e um touchupinside.

Ao vincular, eu só uso a tomada:

set.Bind (somethingOutlet).For ("TouchUpInside").To(vm => vm.Something);

Tudo o que eu precisava fazer era remover a conexão de ação (touchupinside) no Xcode e isso a resolveu.

PS Acho que isso está em sua base, tudo relacionado às respostas anteriores e a @chris kaminski em particular, mas espero que isso ajude alguém ...

Felicidades.

Eu tive o mesmo problema. O problema para mim era que um botão tinha dois métodos de ação. O que fiz foi criar um primeiro método de ação para o meu botão e depois excluí -lo no controlador de exibição, mas esqueci de desconectar a conexão no storyboard principal do Inspetor de conexão. Então, quando adicionei um segundo método de ação, agora havia dois métodos de ação para um botão, o que causou o erro.

Para mim, foi uma conexão restante criada no interfaceBuilder Bij Ctrl-Dragging. O nome da conexão quebrada estava no log de erro

*** Terminating app due to uncaught exception 'NSInvalidArgumentException',
reason: '-[NameOfYourApp.NameOfYourClass nameOfCorruptConnection:]:
unrecognized selector sent to instance 0x7f97a48bb000'

Eu tinha uma ação vinculada a um botão. Pressionar o botão travou o aplicativo porque a tomada não existia mais no meu código. Procurar o nome no log me levou a ele no storyboard. Excluiu, e o acidente se foi!

No meu caso, resolvi o problema após 2 horas:

O remetente (um item tabbar) não estava tendo nenhuma saída de referência. Então estava apontando para lugar nenhum.

Juste Crie uma saída de referência correspondente à sua função.

Espero que isso possa ajudar vocês.

Estou respondendo a Leonard Challis, já que eu também estava pegando a classe C193P de Stanford iOS, assim como o usuário "Oli206"

"Terminando o aplicativo devido à exceção não capturada 'nsinvalidargumentException', razão:"

O problema era que eu tinha o botão "Enter" na calculadora conectada duas vezes, e um amigo apontou que fazer uma inspeção do botão no storyboard mostrou que duas entradas estavam nos atributos "tocar dentro" quando cliquei com o botão direito do mouse o botão "Enter". Apagar um dos dois "tocados dentro" "enviou eventos" resolveu o problema.

Isso mostrou que o problema é acionado (para a classe de vídeo C193P na explicação da calculadora na atribuição 1) como 2 eventos enviados, um dos quais estava causando a exceção.

Isso pode acontecer quando você não atribui o ViewController ao ViewControllerscene no interfaceBuilder. Portanto, o ViewController.m não está conectado a nenhuma cena.

Incluindo minha parte. Fiquei preso nisso por um tempo, até que percebi que criei um projeto com ARC (referência de contagem automática) Desativado. Um conjunto rápido para sim nessa opção resolveu meu problema.

Outra causa realmente boba disso é ter o seletor definido na interface (.h), mas não na implementação (.m) (erro de digitação)

Outra razão/solução para adicionar à lista. Este é causado por iOS6.0 (e/ou programação ruim). Nas versões mais antigas, o seletor corresponderia se os tipos de parâmetros correspondessem, mas no iOS 6.0 eu obtive falhas no código de trabalho anteriormente, onde o nome do parâmetro não estava correto.

Eu estava fazendo algo como

[objectName methodName:@"somestring" lat:latValue lng:lngValue];

mas na definição (tanto .h quanto .m) eu tive

(viod) methodName:(NSString *) latitude:(double)latitude longitude:(double)longitude;

Isso funcionou bem no iOS5, mas não em 6, mesmo a mesma compilação implantada para diferentes dispositivos.

Não entendo por que o compilador não me diz isso, de qualquer maneira - o problema solou.

Isso também pode acontecer quando você deseja definir uma propriedade de um Controllera para uma propriedade pública dentro de uma classe Custom Controllerb e ainda não definiu a "classe personalizada" dentro do Inspetor de Identidade nos storyboards ainda.

Meu problema e solução foram diferentes e pensei em publicá -lo aqui para que futuros leitores possam salvar a cabeça de bater na parede.

Eu estava alocando o XIB diferente para o mesmo UIViewController e, mesmo depois de pesquisar em todos os lugares, não consegui encontrar como corrigi -lo. Então eu verifiquei meu appdelegate onde estava ligando initWithNibName e posso ver que, ao copiar o código, mudei o nome do XIB, mas esqueci de mudar UIViewController classe. Portanto, se nenhuma solução funcionar para você, verifique seu initWithNibName método.

Aconteceu comigo por causa de argumentos de restrição conflitantes.

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