ios - uitableviewcell - ¿Cómo puedo depurar el error del "selector no reconocido enviado a la instancia"?
uitableviewcell swift (9)
Estoy creando una vista de celda de tabla personalizada para mi vista de tabla. Después de conectar una vista de imagen de una celda personalizada (en el guión gráfico) a mi código rápidamente, 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
)
¿Puedes 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.
El primer paso crítico es analizar el mensaje de error:
[UITableViewCellContentView image]: unrecognized selector sent to instance
Esto le dice que la image
del "mensaje" fue "enviada" a un objeto de la clase UITableViewCellContentView. (En otras palabras, se intentó llamar a la image
del método en 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 método de Image
, pero no un método de image
, por lo que se utilizó el nombre del método incorrecto en la llamada. O puede ser que el método nombrado sea someMethod:someParm:
pero la clase implementa someMethod:someParm:anotherParm:
lo que significa que se omitió un parámetro en la llamada.
Sin embargo, lo más frecuente es que la clase nombrada no tenga ningún método que se parezca vagamente al método nombrado, lo que significa que de alguna manera se utilizó 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 obtenga un error en la línea de:
[__NSDictionaryI objectAtIndex:] unrecognized selector sent to instance
porque el objeto recuperado de myDictionary
era, de hecho, un NSDictionary, no el NSArray que se esperaba.
Lo más confuso, desafortunadamente, es cuando este tipo de error ocurre en lo profundo del código del sistema UI en lugar de en su propio código. Esto puede suceder cuando, de alguna manera, se pasa el objeto incorrecto a la interfaz del sistema o tal vez se configura la clase incorrecta en Interface Builder o donde sea.
En estos escenarios, he encontrado útil mirar dos cosas
- La pila de llamadas
- Las variables locales (y sus tipos) en cada marco de pila
Cuando tuve 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 cumpla con los requisitos de una clase principal (dado que su instancia de ItemTableViewCell es la que más hereda).
¿Puede mostrarnos el código de su clase ItemTableViewCell?
Intente configurar un punto de corte simbólico en -[NSObject(NSObject) doesNotRecognizeSelector:]
. Simplemente haga clic en [+]
en la esquina inferior izquierda de Breakpoint Navigator para agregar un punto de interrupción. Luego haga clic en ''Agregar punto de ruptura simbólico''. Reproducir su bloqueo ahora debería darle una mejor idea de en qué parte del código se produce el problema.
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 arroja una excepción porque el nuevo objeto no comprende ese mensaje.
Para diagnosticar este problema, ejecute Profiler con la detección de ''Zombies''.
Puede rastrear fácilmente dichos bloqueos utilizando los Exception Breakpoints
.
Abra el Breakpoint Navigator
y agregue el
Una vez que agregue el Punto de interrupción de excepción, se abrirá la opción para elegir la Exception
.
Seleccione Objective-C
.
Ejecute el código y bloquee la aplicación, el punto de interrupción lo detendrá hasta el punto donde el código se bloquea.
Puede usar Introspection para averiguar si el objeto responde a un selector en particular o no.
let canWork = yourObject.respondsToSelector(Selector("image")) // true
Solo si es verdad que el código funcionará ... de lo contrario, se bloqueará con seguridad
Puede usar 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
}
}
Tuve el mismo problema, y esto funcionó para mí:
Reemplaza el isEqual en tu SKScene:
- (BOOL)isEqual:(id)other {
if (![other isMemberOfClass:[SKScene class]]) {
return false;
}
return [super isEqual:other];
}
indexPath
pasar indexPath
para 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
}