Errore "selettore non riconosciuto inviato all'istanza" in Objective-C


155

Ho creato un pulsante e aggiunto un'azione per esso, ma non appena è stato invocato, ho ricevuto questo errore:

-[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'

Questo è il mio codice:

- (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(@"---");
}

Risposte:


187

Sembra che tu non stia gestendo correttamente il controller di visualizzazione e che ad un certo punto venga deallocato, il che provoca l' numberButtonClicked:invio del metodo a un altro oggetto che ora occupa la memoria che il controller di visualizzazione occupava in precedenza ...

Assicurati di conservare / rilasciare correttamente il controller della vista.


105
È una diagnosi molto astuta da poche righe di codice.
Michael Morrison,

41
OK, quindi il problema è stato identificato ... ma "Assicurati di conservare / rilasciare correttamente il controller di visualizzazione". è un suggerimento, non una soluzione.
Alex Gray,

12
@alex gray, che cosa? La corretta gestione della memoria sul controller della vista ha risolto il problema ... Non capisco come non sia una soluzione?
Jasarien,

28
corretta. anche se questo sembra essere "la soluzione" .. e potrei essere in minoranza, (anche se riesco ancora a esistere), ma la connessione tra il problema e la soluzione non è immediatamente ovvia. per esempio, sto incontrando -[NSWindow end]: unrecognized selector sent to instance 0x100523e80 e sebbene realizzi le somiglianze con il PO, e forse anche la causa del problema dalla tua risposta, l'implementazione di una correzione non è immediatamente ovvia
Alex Gray,

12
È immediatamente ovvio. La gestione della memoria di NSWindow non è corretta da qualche parte lungo la linea. Passa attraverso il suo ciclo di vita e correggilo.
Jasarien,

127

Per quelli che arrivano qui tramite Google come ho fatto io, che probabilmente riguarda di più Xcode 4.2 + / iOS 5+ di più, per quanto riguarda ARC. Ho avuto lo stesso errore " Selettore non riconosciuto inviato all'istanza ". Nel mio caso avevo impostato un'azione target di UIButton per passare se stesso come parametro del mittente, ma in seguito mi sono reso conto che non ne avevo bisogno e l'ho rimosso nel codice. Quindi, qualcosa del tipo:

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

È stato modificato in:

- (IBAction)buttonPressed {

Fare clic con il tasto destro del mouse sul pulsante UIB in questione ha mostrato che l'evento Ritocco interno era associato al pulsante dei controller di visualizzazione. Rimuovere questo e riassegnarlo al metodo modificato ha funzionato a meraviglia.


Questo è stato molto utile, anche se penso che la sua stessa domanda e risposta faciliterebbe la ricerca.
Curtis Inderwiesche,

@LeonardChallis Come puoi fare riferimento al mittente in buttonPressed se non viene passato come parametro?
zakdances,

8
Risposta molto utile Ho appena incontrato questo esatto problema e la tua soluzione era esattamente giusta. Stava seguendo la lezione di Stanford per iOS su iTunesU quando questo è successo. Grazie ancora per la tua risposta!
Marshall Alsup,

1
@LeonardChallis Grazie. Ho aggiunto una risposta gratuita alla tua risposta.
1,21 gigawatt

1
Stavo solo affrontando un problema simile, ho rimosso il parametro mittente dalla funzione di selezione e poi mi sono chiesto come ottenere il mittente. Nel mio caso, stavo ricevendo l'errore perché ho dimenticato di inserire i due punti dopo il callback del selettore, causando così una mancata corrispondenza della sequenza di chiamate. Con i due punti, posso mantenere l'argomento mittente.

74

Questa è stata la migliore risposta di Google per questo problema, ma ho avuto una causa / risultato diverso - ho pensato di aggiungere i miei due centesimi nel caso in cui altri si imbattessero in questo problema.

Ho avuto un problema simile proprio stamattina. Ho scoperto che se fai clic con il pulsante destro del mouse sull'interfaccia utente che ti dà il problema, puoi vedere quali connessioni sono state create. Nel mio caso avevo un pulsante collegato a due azioni. Ho eliminato le azioni dal menu di scelta rapida e le ho ricablate e il mio problema è stato risolto.

Quindi assicurati che le tue azioni siano collegate correttamente.


Questo era il mio problema Ho rinominato una funzione e modificato il mio codice ma non ho modificato la connessione nel file xib.
BFTrick,

2
GRAZIE! Si è scoperto che avevo tre metodi a cui avevo eliminato ancora riferimento. Mi dà fastidio per una settimana!
erdekhayser,

25

OK, devo fare il chip qui. L'OP ha creato dinamicamente il pulsante . Ho avuto un problema simile e la risposta (dopo ore di caccia) è così semplice che mi ha fatto star male.

Quando si usa:

action:@selector(xxxButtonClick:)

or (as in my case)

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

Se si posizionano i due punti alla fine della stringa, passerà il mittente. Se non si posizionano i due punti alla fine della stringa, non lo sarà e il ricevitore riceverà un errore se ne prevede uno. È facile perdere i due punti se si sta creando dinamicamente il nome dell'evento.

Le opzioni del codice del ricevitore si presentano così:

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

Come sempre, è sempre la risposta ovvia che ci si perde.


1
Grazie mille! Questo era il mio problema (non mettere i due punti ":" alla fine del nome del selettore). Come mai sono quasi sempre le cose più stupide a farci sbattere la testa contro il muro alle 3 del mattino? Grazie davvero!
Destra

23

Nel mio caso la funzione non si aspettava un argomento ma il pulsante era configurato per inviarne uno che causava l'errore. Per risolvere questo problema ho dovuto ricollegare il gestore dell'evento.

Ecco la mia funzione:

inserisci qui la descrizione dell'immagine

Si noti che non contiene argomenti.

Ecco un'immagine della mia configurazione del pulsante (fare clic destro sul pulsante per visualizzarlo):

inserisci qui la descrizione dell'immagine

Si noti che ci sono 3 gestori di eventi.

Per risolvere questo problema, ho dovuto rimuovere ciascuno degli elementi dell'evento poiché uno di essi stava inviando un riferimento a se stesso alla funzione enterPressed. Per rimuovere questi elementi ho fatto clic sulla piccola icona x accanto al nome di ciascun elemento fino a quando non sono stati visualizzati elementi.

inserisci qui la descrizione dell'immagine

Successivamente ho dovuto ricollegare il pulsante all'evento. Per fare ciò, tieni premuto il tasto Ctrl e trascina una linea dal pulsante all'azione. Dovrebbe essere indicato "Connetti azione". Nota: ho dovuto riavviare XCode per farlo funzionare per qualche motivo; altrimenti mi permette solo di inserire azioni (ovvero creare una nuova azione) sopra o sotto la funzione.

inserisci qui la descrizione dell'immagine

Ora dovresti avere un singolo gestore eventi collegato all'evento button che non passa argomenti:

inserisci qui la descrizione dell'immagine

Questa risposta completa la risposta di @Leonard Challis che dovresti leggere anche tu.


14

Questo può accadere anche se non si imposta la "Classe" della vista nel builder di interfacce.


Grazie mille! Ciò stava causando il crash della mia app in seguito, appena dimenticato di impostare la classe del controller.
Eichhörnchen,

Perché ha bisogno di conoscere la classe? Sto cercando di utilizzare un UITableViewSection come UIView e quindi sto ricevendo questo errore. Il compilatore dice che UITableViewSection non esiste, quindi presumo che sia interno a UIKit.
Ian Warburton,

13

Nel mio caso, stavo usando NSNotificationCenter e stavo tentando di usare un selettore che non accettava argomenti, ma aggiungeva due punti. La rimozione dei due punti ha risolto il problema.

Quando si utilizza un nome selettore, non utilizzare i due punti finali se non ci sono argomenti. Se c'è un argomento, usa due punti finali. Se sono presenti più argomenti, è necessario denominarli insieme a due punti finali per ciascun argomento.

Vedi la risposta di Adam Rosenfield qui: Selettori in Objective-C?


11

Ho avuto questo problema con un progetto Swift in cui sto creando i pulsanti in modo dinamico. Codice 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).")
}

La soluzione era quella di aggiungere due punti ":" dopo l'azione: ad es

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).")
    }

Esempio completo qui: https://developer.apple.com/library/content/samplecode/UICatalog/Listings/Swift_UIKitCatalog_DefaultToolbarViewController_swift.html


Subito dopo aver seguito il tutorial e letto un suggerimento su questo stesso identico problema, mi sono
innamorato di

6

La causa più ovvia di ciò (inclusa per completezza) è erroneamente lanciare un puntatore e chiamare un metodo della classe sbagliata.

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

Questo è un buon suggerimento: non sottoclassare una vista o un oggetto dati (ad es. Non riuscendo ad aggiungere il nome della sottoclasse) è un altro modo in cui ciò accade
Brad M

4

Ho avuto anche lo stesso problema.

Ho cancellato il mio uibutton nello storyboard e lo ho ricreato .. ora tutto funziona bene.


3

Ho avuto un problema simile, ma per me la soluzione era leggermente diversa. Nel mio caso, ho usato una Categoria per estendere una classe esistente (UIImage per alcune funzionalità di ridimensionamento - vedi questo howto nel caso ti interessi) e ho dimenticato di aggiungere il file * .m alla destinazione di compilazione. Stupido errore, ma non sempre ovvio quando succede dove cercare. Ho pensato che valesse la pena condividere ...


3

Questo è successo a me perché ho cancellato accidentalmente il "@IBAction func ..." all'interno del mio codice di classe UIViewcontroller, quindi nello Storyboard è stato creato lo Outlet di riferimento, ma in fase di esecuzione c'era una funzione per elaborarlo.

La soluzione era eliminare il riferimento Outlet all'interno della finestra di ispezione proprietà e quindi ricrearlo trascinando con il tasto comando sul codice di classe.

Spero che sia d'aiuto!


Allo stesso modo, ciò è accaduto anche a me quando il pulsante faceva riferimento a una funzione che non esisteva più.
Josh Wolff,

2

Penso che dovresti usare il vuoto, invece dell'IBAction nel tipo di ritorno. perché hai definito un pulsante a livello di codice.


2

Un'altra possibile soluzione: aggiungi '-ObjC' agli argomenti del tuo linker.

La spiegazione completa è qui: Categorie di obiettivi-C nella libreria statica

Credo che l'essenziale sia: se la categoria è definita in una libreria con cui si sta collegando staticamente, il linker non è abbastanza intelligente da collegarsi ai metodi di categoria. Il flag qui sopra rende il linker linker in tutte le classi e categorie di obiettivi C, non solo quelle che ritiene debbano basarsi sull'analisi della fonte. (Sentiti libero di mettere a punto o correggere quella risposta. Conosco lingue collegate, quindi sto solo facendo da pappagallo).


2

Ho avuto lo stesso errore e ho scoperto quanto segue:

Quando si utilizza il codice

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

Potresti pensare che stia cercando il selettore:

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

Ma in realtà sta cercando il selettore:

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

Quel selettore non esiste, quindi ottieni l'incidente.

È possibile modificare il selettore per ricevere il mittente (id) al fine di risolvere l'errore.

Ma cosa succede se si dispone di altre funzioni che chiamano la funzione di aggiornamento senza fornire un mittente? È necessaria una funzione che funzioni per entrambi. La soluzione semplice è aggiungere un'altra funzione:

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

E quindi modifica il codice a tendina di aggiornamento per chiamare invece quel selettore:

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

Sto anche facendo il corso Stanford per iOS su un Mac più vecchio che non può essere aggiornato alla versione più recente di Mac OSX. Quindi sto ancora costruendo per iOS 6.1, e questo ha risolto il problema per me.


2

Nel mio caso ho risolto il problema dopo 2 ore:

Il mittente (un elemento tabBar) non aveva alcun punto di riferimento . Quindi non puntava da nessuna parte.

Juste crea un punto di riferimento corrispondente alla tua funzione.

Spero che questo possa aiutarti ragazzi.


Solo per aggiungere, nel mio caso ho dimenticato di portare un IBActionsu Swift. Quindi si lamentava di voler chiamare quella funzione, ma non è stato possibile trovarla.
DevNebulae

1

Attualmente sto imparando lo sviluppo iOS e sfogliando il libro "Inizio dello sviluppo iOS6" di aPress. Stavo ottenendo lo stesso errore nel Capitolo 10: Storyboard.

Mi ci sono voluti due giorni per capirlo, ma ho scoperto che ho accidentalmente impostato il tag della cella TableView su 1 quando non avrei dovuto. Per chiunque altro stia facendo questo libro e riceva un errore simile spero che questo aiuti.

Spero davvero che errori futuri nel mio codice siano più facili da trovare! Hahaha. L'errore di debug non ha fatto nulla per spingermi nella giusta direzione per capirlo (o almeno sono troppo nuovo per capire il debugger, lol).


1

Nel mio caso stavo usando un UIWebView e ho passato una NSString nel secondo parametro anziché un NSURL. Quindi sospetto che tipi di classe errati passati a una funzione possano causare questo errore.


1

..E ora mio

Avevo il pulsante collegato a un metodo che accedeva al parametro di un altro pulsante e che funzionava benissimo MA non appena ho provato a fare qualcosa con il pulsante stesso, ho avuto un crash. Durante la compilazione, non è stato visualizzato alcun errore. Soluzione?

Non sono riuscito a collegare il pulsante al proprietario del file. Quindi se qualcuno qui è stupido come me, prova questo :)


1

Ancora un'altra soluzione / caso leggermente diverso.

Sto usando Xamarin e MvvmCross e stavo cercando di associare l'UIButton a un ViewModel. Avevo il UIButton collegato a una presa e un TouchUpInside.

Quando rilevo uso solo l'Outlet:

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

Tutto quello che dovevo fare era rimuovere la connessione dell'azione (TouchUpInside) in XCode e questo l'ha risolto.

PS Immagino che questo sia nella sua base tutto legato alle risposte precedenti e in particolare a @Chris Kaminski, ma spero che questo aiuti qualcuno ...

Saluti.


1

Ho avuto lo stesso problema. Il problema per me era che un pulsante aveva due metodi di azione. Quello che ho fatto è stato creare un primo metodo di azione per il mio pulsante e poi cancellarlo nel controller di visualizzazione, ma ho dimenticato di disconnettere la connessione nello storyboard principale nella finestra di ispezione delle connessioni. Quindi, quando ho aggiunto un secondo metodo di azione, ora c'erano due metodi di azione per un pulsante, che ha causato l'errore.


1

Per me, è stata una connessione rimanente creata in Interfacebuilder bij ctrl-trascinamento. Il nome della connessione interrotta era nel registro degli errori

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

Ho avuto un'azione collegata a un pulsante. Premendo il pulsante si è bloccata l'app perché l'Outlet non esisteva più nel mio codice. La ricerca del nome nel registro mi ha portato ad esso nello storyboard. L'ho eliminato e l'incidente era sparito!


0

Sto rispondendo a Leonard Challis, dato che stavo anche prendendo la Stanford iOS classe C193P, così come l'utente "oli206"

"Chiusura dell'app a causa dell'eccezione non rilevata" NSInvalidArgumentException ", motivo:"

Il problema era che avevo collegato il pulsante "Invio" sulla calcolatrice due volte, e un amico ha sottolineato che facendo un'ispezione del pulsante nello Storyboard ha mostrato che 2 voci erano sugli attributi "Ritocca dentro" quando ho cliccato con il tasto destro del mouse su il pulsante "Invio". La cancellazione di uno dei due "Eventi ritoccati" ha risolto il problema.

Ciò ha dimostrato che il problema è stato attivato (per la classe video C193P sulla Calcolatrice Soluzione sull'assegnazione 1) come 2 eventi inviati, uno dei quali ha causato l'eccezione.


Ho avuto 3 voci in qualche modo. :)
1,21 gigawatt

0

Può accadere quando non si assegna ViewController a ViewControllerScene in InterfaceBuilder. Quindi ViewController.m non è collegato a nessuna scena.



0

Un'altra causa davvero sciocca di questo è avere il selettore definito nell'interfaccia (.h) ma non nell'implementazione (.m) (pe typo)


0

Un altro motivo / soluzione da aggiungere all'elenco. Questo è causato da iOS6.0 (e / o cattiva programmazione). Nelle versioni precedenti il ​​selettore corrisponderebbe se i tipi di parametro corrispondessero, ma in iOS 6.0 ho avuto arresti anomali nel codice precedentemente funzionante in cui il nome del parametro non era corretto.

Stavo facendo qualcosa del genere

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

ma nella definizione (sia .h che .m) avevo

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

Funzionava perfettamente su iOS5 ma non su 6, anche la stessa identica build distribuita su dispositivi diversi.

Non capisco perché il compilatore non potesse dirmelo, comunque - il problema è stato risolto.


0

Ciò può accadere anche quando si desidera impostare una proprietà da un ControllerA a una proprietà pubblica all'interno di una classe ControllerB personalizzata e non si è ancora impostata la "Classe personalizzata" all'interno della finestra di ispezione identità negli storyboard.


0

Il mio problema e la mia soluzione erano diversi e pensavo che avrei dovuto pubblicarlo qui in modo che i futuri lettori potessero salvarsi la testa dal sbattere contro il muro.

Stavo allocando xib diversi sullo stesso UIVIewController e anche dopo aver cercato ovunque non sono riuscito a trovare come correggerlo. Quindi ho controllato il mio AppDelegate dove stavo chiamando initWithNibNamee posso vedere che durante la copia del codice ho cambiato il nome xib, ma ho dimenticato di cambiare UIViewControllerclasse. Quindi, se nessuna delle soluzioni funziona per te, controlla il tuo initWithNibNamemetodo.


0

Mi è successo a causa di argomenti di vincolo contrastanti.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.