Come posso eseguire il debug dell'errore "selettore non riconosciuto inviato all'istanza"


100

Sto creando una vista cella di tabella personalizzata per la mia vista tabella. Dopo aver collegato una visualizzazione immagine della cella personalizzata (nello storyboard) al mio codice in swift, ottengo il seguente errore.

[UITableViewCellContentView image]: unrecognized selector sent to instance 0x7fb4fad7fd20'
*** First throw call stack:
(
    0   CoreFoundation                      0x000000010ccbb3f5 __exceptionPreprocess + 165
    1   libobjc.A.dylib                     0x000000010e7e9bb7 objc_exception_throw + 45
    2   CoreFoundation                      0x000000010ccc250d -[NSObject(NSObject) doesNotRecognizeSelector:] + 205
    3   CoreFoundation                      0x000000010cc1a7fc ___forwarding___ + 988
    4   CoreFoundation                      0x000000010cc1a398 _CF_forwarding_prep_0 + 120
    5   UIKit                               0x000000010d7d8881 -[UITableViewCell _marginWidth] + 151
    6   UIKit                               0x000000010d7ca23d -[UITableViewCell _separatorFrame] + 70
    7   UIKit                               0x000000010d7ca6fa -[UITableViewCell _updateSeparatorContent] + 360
    8   UIKit                               0x000000010d7d4e85 -[UITableViewCell _setSectionLocation:animated:forceBackgroundSetup:] + 1174
    9   UIKit                               0x000000010d634ea8 __53-[UITableView _configureCellForDisplay:forIndexPath:]_block_invoke + 1822
    10  UIKit                               0x000000010d5b5eae +[UIView(Animation) performWithoutAnimation:] + 65
    11  UIKit                               0x000000010d63477b -[UITableView _configureCellForDisplay:forIndexPath:] + 312
    12  UIKit                               0x000000010d63bcec -[UITableView _createPreparedCellForGlobalRow:withIndexPath:willDisplay:] + 533
    13  UIKit                               0x000000010d61b7f1 -[UITableView _updateVisibleCellsNow:isRecursive:] + 2846
    14  UIKit                               0x000000010d63165c -[UITableView layoutSubviews] + 213
    15  UIKit                               0x000000010d5be199 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 521
    16  QuartzCore                          0x00000001114b6f98 -[CALayer layoutSublayers] + 150
    17  QuartzCore                          0x00000001114abbbe _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE + 380
    18  QuartzCore                          0x00000001114aba2e _ZN2CA5Layer28layout_and_display_if_neededEPNS_11TransactionE + 24
    19  QuartzCore                          0x0000000111419ade _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 242
    20  QuartzCore                          0x000000011141abea _ZN2CA11Transaction6commitEv + 390
    21  QuartzCore                          0x000000011141b255 _ZN2CA11Transaction17observer_callbackEP19__CFRunLoopObservermPv + 89
    22  CoreFoundation                      0x000000010cbf0347 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 23
    23  CoreFoundation                      0x000000010cbf02a0 __CFRunLoopDoObservers + 368
    24  CoreFoundation                      0x000000010cbe60d3 __CFRunLoopRun + 1123
    25  CoreFoundation                      0x000000010cbe5a06 CFRunLoopRunSpecific + 470
    26  GraphicsServices                    0x0000000110daa9f0 GSEventRunModal + 161
    27  UIKit                               0x000000010d545550 UIApplicationMain + 1282
    28  TestWork                          0x000000010caa432e top_level_code + 78
    29  TestWork                          0x000000010caa436a main + 42
    30  libdyld.dylib                       0x000000010efc3145 start + 1
    31  ???                                 0x0000000000000001 0x0 + 1
)

Puoi dirmi come risolvere questo errore?

Grazie.

Aggiungo un punto di interruzione di eccezione nel mio progetto.

Questa è la linea in cui si interrompe.

  override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = self.tableView.dequeueReusableCellWithIdentifier(kCellIdentifier) as ItemTableViewCell  <---------------

Ma non uso "immagine" nel mio codice.


2
stai chiamando image]da qualche parte .. ma sull'oggetto sbagliato. la prima riga dell'errore ti dice molto
ccwasden

1
Smetti di chiamare [immagine] su UITableViewCellContentView - questo risolverebbe il problema. Mostraci il codice che causa questo arresto anomalo.
Grzegorz Krukowski

1
Penso che tu abbia usato qualche immagine in tableViewCell ma quell'immagine potrebbe non essere nel tuo pacchetto.
Nand Parikh

Risposte:


102

Prova a impostare un punto di interruzione simbolico -[NSObject(NSObject) doesNotRecognizeSelector:]. È sufficiente fare clic [+]nell'angolo inferiore sinistro del Navigatore punti di interruzione per aggiungere un punto di interruzione. Quindi fare clic su "Aggiungi punto di interruzione simbolico". La riproduzione dell'arresto anomalo ora dovrebbe darti un'idea migliore di dove si verifica il problema nel codice.

inserisci qui la descrizione dell'immagine


17
Potrebbe anche solo aggiungere un punto di interruzione dell'eccezione .
rebello95

1
Mi ha salvato la giornata, fratello.
AntiMoron

1
Grazie è così utile
Mohd Sadham

35

Puoi facilmente tenere traccia di tali arresti anomali utilizzando Exception Breakpoints.

Apri il Breakpoint Navigatore aggiungi il file

inserisci qui la descrizione dell'immagine

Dopo aver aggiunto il punto di interruzione dell'eccezione, sarà aperta l'opzione per scegliere il file Exception.

inserisci qui la descrizione dell'immagine

Selezionare Objective-C .

Esegui il codice e blocca l'applicazione, il punto di interruzione ti fermerà al punto in cui il codice si blocca.


Succede su AppDelegate riga 1. E adesso? :(
Daniel Springer

Puoi mostrare parte del tuo codice scritto in AppDelegate? Dove sta mettendo in pausa il punto di interruzione. E anche i registri.
Vatsal K

si ferma sulla linea 1, dove viene dichiarato il delegato dell'app
Daniel Springer il

Ci sono alcuni casi in cui si interrompe, a causa di alcuni framework, ma non preoccuparti che potresti dover premere il pulsante Continua per 3-4 volte per eseguire l'applicazione.
Vatsal K

Non è un errore in questo caso, alcuni vecchi framework stanno causando questo tipo di problema. Prova ad aggiornare i tuoi vecchi framework a quelli nuovi / aggiornati. Questo dovrebbe risolvere il problema.
Vatsal K

30

Il primo passaggio critico è analizzare il messaggio di errore:

[UITableViewCellContentView image]: unrecognized selector sent to instance

Questo ti dice che il "messaggio" è imagestato "inviato" a un oggetto della classe UITableViewCellContentView. (In altre parole, è stato effettuato un tentativo di chiamare il metodoimage su un oggetto della classe UITableViewCellContentView.)

La prima cosa da chiedere è "Ha senso?" È possibile che la classe denominata abbia un Imagemetodo, ma non un imagemetodo, quindi nella chiamata è stato utilizzato il nome del metodo sbagliato. Oppure può essere che il metodo denominato lo sia someMethod:someParm:, ma la classe implementasomeMethod:someParm:anotherParm: , il che significa che un parametro è stato omesso nella chiamata.

Molto spesso, tuttavia, la classe denominata non ha alcun metodo che somigli vagamente al metodo denominato, il che significa che in qualche modo è stato utilizzato un puntatore all'oggetto sbagliato nella chiamata fallita.

Ad esempio, si potrebbe fare:

NSArray* myArray = [myDictionary objectForKey:@"values"];
NSString* myString = [myArray objectAtIndex:5];

E ottieni un errore sulla falsariga di:

[__NSDictionaryI objectAtIndex:] unrecognized selector sent to instance

perché l'oggetto recuperato da myDictionaryera, in effetti, un NSDictionary, non l'NSArray previsto.

La cosa più confusa, sfortunatamente, è quando questo tipo di errore si verifica in profondità nel codice di sistema dell'interfaccia utente piuttosto che nel tuo codice. Questo può accadere quando in qualche modo hai passato l'oggetto sbagliato a un'interfaccia di sistema, o forse hai configurato la classe sbagliata in Interface Builder o ovunque.


6

Un altro motivo possibile è che l'oggetto originale è stato distrutto e quindi un altro oggetto è stato allocato allo stesso indirizzo di memoria. Quindi il tuo codice invia il messaggio, pensando che abbia ancora un puntatore al vecchio oggetto, e Objective-C lancia un'eccezione perché il nuovo oggetto non comprende quel messaggio.

Per diagnosticare questo problema, esegui il Profiler con il rilevamento di "Zombi".


2

Swift 5.0

È possibile utilizzare Introspezione per scoprire se l'oggetto risponde o meno a un particolare selettore.

let canWork = yourObject.respondsToSelector(Selector("image"))   // true

Solo se è vero che il codice funzionerà .. altrimenti andrà in crash di sicuro


1

In questi scenari ho trovato utile esaminare due cose

  1. Lo stack di chiamate
  2. Le variabili locali (e i loro tipi) in ogni stack frame

Quando ho riscontrato questo errore, di solito è perché ho inviato un messaggio a un'istanza di tipo A, quando mi aspettavo il tipo B.

In questo scenario specifico, potresti non soddisfare un requisito di una classe padre (data la tua istanza di ItemTableViewCell molto probabilmente eredita).

Puoi forse mostrarci il codice per la tua classe ItemTableViewCell?


1

È possibile utilizzare il codice seguente per dichiarare la variabile:

let noteListTableViewCellobject = "NoteListTableViewCell";` `// Note listTablecell create custom cell`

func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {

    var cell:NoteListTableViewCell? = tableView.dequeueReusableCellWithIdentifier(noteListTableViewCellobject) as? NoteListTableViewCell

    if (cell == nil) {
        let nib:Array = NSBundle.mainBundle().loadNibNamed("NoteListTableViewCell", owner: self, options: nil)
        cell = nib[0] as? NoteListTableViewCell
    }
}

0

Ho avuto lo stesso problema e questo ha funzionato per me:

Sostituisci isEqual nel tuo SKScene:

- (BOOL)isEqual:(id)other {

    if (![other isMemberOfClass:[SKScene class]]) {
        return false;
    }
    return [super isEqual:other];
}

0

Devi passare indexPathper dichiarare l'oggetto della cella tableview.

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath)

    return cell
}
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.