¿Cómo puedo depurar el error "selector no reconocido enviado a la instancia"?

100

Estoy creando una vista de celda de tabla personalizada para mi vista de tabla. Después de conectar una vista de imagen de celda personalizada (en el guión gráfico) a mi código en rápido, aparece el siguiente error.

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

¿Puede decirme cómo resolver este error?

Gracias.

Agrego un punto de interrupción de excepción en mi proyecto.

Esta es la línea donde se rompe.

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

Pero no uso 'imagen' en mi código.

n179911
fuente
2
está llamando a image]alguna parte ... pero en el objeto incorrecto. la primera línea del error te dice mucho
ccwasden
1
Deje de llamar a [imagen] en UITableViewCellContentView, eso lo arreglaría. Muéstranos el código que está causando este bloqueo.
Grzegorz Krukowski
1
Creo que ha utilizado alguna imagen en tableViewCell, pero es posible que esa imagen no esté en su paquete.
Nand Parikh

Respuestas:

102

Intente establecer un punto de interrupción simbólico -[NSObject(NSObject) doesNotRecognizeSelector:]. Simplemente haga clic [+]en en la esquina inferior izquierda del navegador de puntos de interrupción para agregar un punto de interrupción. Luego haga clic en 'Agregar punto de interrupción simbólico'. Reproducir su bloqueo ahora debería darle una mejor idea de dónde ocurre el problema en su código.

ingrese la descripción de la imagen aquí

dbart
fuente
17
También podría agregar un punto de interrupción de excepción .
rebello95
1
Salvó mi día, hermano.
AntiMoron
1
Gracias, es tan útil
Mohd Sadham
35

Puede rastrear fácilmente tales bloqueos usando Exception Breakpoints.

Abra el Breakpoint Navigatory agregue el

ingrese la descripción de la imagen aquí

Una vez que agregue el punto de interrupción de excepción, se abrirá la opción para elegir el Exception.

ingrese la descripción de la imagen aquí

Seleccione Objective-C.

Ejecute el código y bloquee la aplicación, el punto de interrupción lo detendrá hasta el punto en que el código se bloquee.

Vatsal K
fuente
Sucede en la línea 1 de AppDelegate. ¿Y ahora qué? :(
Daniel Springer
¿Puede mostrar algo de su código escrito en AppDelegate? Donde está pausando el punto de ruptura. Y también los troncos.
Vatsal K
se detiene en la línea 1, donde se declara el delegado de la aplicación
Daniel Springer
Hay algunos casos en los que se detiene, debido a algunos marcos, pero no se preocupe, es posible que deba presionar el botón Continuar durante 3-4 veces para ejecutar la aplicación.
Vatsal K
Eso no es un error en tal caso. Algunos marcos antiguos están causando este tipo de problema. Pruebe actualizando sus marcos antiguos a nuevos / actualizados. Eso debería resolver el problema.
Vatsal K
30

El primer paso crítico es analizar el mensaje de error:

[UITableViewCellContentView image]: unrecognized selector sent to instance

Esto le dice que el "mensaje" imagefue "enviado" a un objeto de clase UITableViewCellContentView. (En otras palabras, se intentó llamar al método imageen un objeto de la clase UITableViewCellContentView).

Lo primero que debe preguntarse es "¿Tiene esto algún sentido?" Puede ser que la clase nombrada tenga un Imagemétodo, pero no un imagemétodo, por lo que se utilizó el nombre de método incorrecto en la llamada. O puede ser que el método nombrado lo sea someMethod:someParm:, pero la clase lo implementa someMethod:someParm:anotherParm:, lo que significa que se omitió un parámetro en la llamada.

Sin embargo, la mayoría de las veces, la clase nombrada no tiene ningún método que se parezca vagamente al método nombrado, lo que significa que de alguna manera se usó un puntero al objeto incorrecto en la llamada fallida.

Por ejemplo, uno podría hacer:

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

Y obtienes un error del tipo:

[__NSDictionaryI objectAtIndex:] unrecognized selector sent to instance

porque el objeto recuperado myDictionaryera, de hecho, un NSDictionary, no el NSArray que se esperaba.

Lo más confuso, desafortunadamente, es cuando este tipo de error ocurre profundamente en el código del sistema de IU en lugar de en su propio código. Esto puede suceder cuando de alguna manera pasó el objeto incorrecto a una interfaz del sistema, o quizás configuró la clase incorrecta en Interface Builder o donde sea.

Lamidas calientes
fuente
6

Otra posible razón es que el objeto original fue destruido y luego otro objeto fue asignado a la misma dirección de memoria. Luego, su código envía el mensaje, pensando que todavía tiene un puntero al objeto anterior, y Objective-C lanza una excepción porque el nuevo objeto no comprende ese mensaje.

Para diagnosticar este problema, ejecute Profiler con detección de 'Zombies'.

Bryan
fuente
2

Swift 5.0

Puede utilizar Introspection para averiguar si el objeto responde a un selector en particular o no.

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

Solo si es cierto que el código funcionará ... de lo contrario, seguro que se bloqueará

Saranjith
fuente
1

En estos escenarios, me ha resultado útil analizar dos cosas

  1. La pila de llamadas
  2. Las variables locales (y sus tipos) en cada marco de pila

Cuando he tenido este error, generalmente es porque envié un mensaje a una instancia de Tipo A, cuando esperaba el Tipo B.

En este escenario específico, es posible que no esté satisfaciendo un requisito de una clase principal (dada su instancia de ItemTableViewCell muy probablemente hereda).

¿Puede mostrarnos el código de su clase ItemTableViewCell?

A B C
fuente
1

Puede utilizar el siguiente código para declarar la variable:

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
    }
}
Yogesh Shelke
fuente
0

Tuve el mismo problema, y ​​esto funcionó para mí:

Anule isEqual en su SKScene:

- (BOOL)isEqual:(id)other {

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

Tienes que pasar indexPathpara declarar el objeto de la celda de vista de tabla.

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

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

    return cell
}
Rohit Parsana
fuente