Ich erstelle eine benutzerdefinierte Tabellenzellansicht für meine Tabellensicht. Nachdem ich eine Bildansicht der benutzerdefinierten Zelle (im Storyboard) mit meinem Code in Swift verbunden habe, erhalte ich die folgende Fehlermeldung.
[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
)
Können Sie mir bitte sagen, wie ich diesen Fehler beheben kann?
Vielen Dank.
Ich füge in meinem Projekt einen Ausnahme-Haltepunkt hinzu.
Dies ist die Linie, in der es bricht.
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = self.tableView.dequeueReusableCellWithIdentifier(kCellIdentifier) as ItemTableViewCell <---------------
Ich benutze aber nicht "image" in meinem Code.
Setzen Sie einen symbolischen Haltepunkt auf -[NSObject(NSObject) doesNotRecognizeSelector:]
. Klicken Sie einfach auf [+]
in der unteren linken Ecke des Haltepunktnavigators, um einen Haltepunkt hinzuzufügen. Klicken Sie anschließend auf "Symbolischen Haltepunkt hinzufügen". Wenn Sie jetzt Ihren Absturz reproduzieren, sollten Sie wissen, wo das Problem auftritt.
Sie können solche Abstürze leicht mit Exception Breakpoints
verfolgen.
Öffnen Sie den Breakpoint Navigator
und fügen Sie den hinzu
Nachdem Sie den Ausnahmepunkt hinzugefügt haben, können Sie die Variable Exception
auswählen.
Wählen Sie Objective-C
.
Führen Sie den Code aus und stürzen Sie die Anwendung ab. Der Haltepunkt hält Sie an dem Punkt, an dem der Code abstürzt.
Der kritische erste Schritt ist die Analyse der Fehlermeldung:
[UITableViewCellContentView image]: unrecognized selector sent to instance
Dies sagt Ihnen, dass die "Nachricht" image
an ein Objekt der Klasse UITableViewCellContentView "gesendet" wurde. (Mit anderen Worten, es wurde versucht, die Methode image
für ein Objekt der Klasse UITableViewCellContentView aufzurufen.)
Das erste, was Sie fragen, ist "Ist das überhaupt sinnvoll?" Es kann sein, dass die benannte Klasse eine Image
-Methode hat, nicht jedoch eine image
-Methode. Daher wurde beim Aufruf der falsche Methodenname verwendet. Oder es kann sein, dass die benannte Methode someMethod:someParm:
ist, die Klasse jedoch someMethod:someParm:anotherParm:
implementiert, was bedeutet, dass ein Parameter beim Aufruf nicht angegeben wurde.
Meistens hat die benannte Klasse jedoch keine Methode, die der benannten Methode nur vage ähnelt, was bedeutet, dass in dem fehlgeschlagenen Aufruf ein Zeiger auf das falsche Objekt verwendet wurde.
Zum Beispiel könnte man folgendes tun:
NSArray* myArray = [myDictionary objectForKey:@"values"];
NSString* myString = [myArray objectAtIndex:5];
Und erhalten Sie einen Fehler im Sinne von:
[__NSDictionaryI objectAtIndex:] unrecognized selector sent to instance
weil das aus myDictionary
abgerufene Objekt tatsächlich ein NSDictionary war, nicht das erwartete NSArray.
Am verwirrendsten ist es leider, wenn diese Art von Fehlern im UI-Systemcode und nicht in Ihrem eigenen Code auftritt. Dies kann passieren, wenn Sie das falsche Objekt irgendwie an eine Systemschnittstelle übergeben oder die falsche Klasse in Interface Builder oder wo auch immer konfiguriert haben.
Ein weiterer möglicher Grund ist, dass das ursprüngliche Objekt zerstört wurde und ein anderes Objekt an derselben Speicheradresse zugewiesen wurde. Dann sendet der Code die Nachricht, da er noch einen Zeiger auf das alte Objekt enthält, und Objective-C löst eine Ausnahme aus, da das neue Objekt diese Nachricht nicht versteht.
Um dieses Problem zu diagnostizieren, führen Sie den Profiler mit der Erkennung von Zombies aus.
In diesen Szenarien fand ich es hilfreich, zwei Dinge zu betrachten
Wenn dieser Fehler aufgetreten ist, liegt dies normalerweise daran, dass ich eine Nachricht an eine Instanz von Typ A gesendet habe, als ich Typ B erwartete.
In diesem bestimmten Szenario erfüllen Sie möglicherweise nicht die Anforderung einer übergeordneten Klasse (da Ihre Instanz von ItemTableViewCell höchstwahrscheinlich erbt).
Können Sie uns vielleicht den Code für Ihre ItemTableViewCell-Klasse zeigen?
Sie können den folgenden Code verwenden, um die Variable zu deklarieren:
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
}
}
Sie müssen indexPath
übergeben, um das Objekt der tableview-Zelle zu deklarieren.
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath)
return cell
}
Ich hatte das gleiche Problem und das funktionierte für mich:
Überschreiben Sie das isEqual in Ihrer SKScene:
- (BOOL)isEqual:(id)other {
if (![other isMemberOfClass:[SKScene class]]) {
return false;
}
return [super isEqual:other];
}
Mit Introspection können Sie herausfinden, ob das Objekt auf einen bestimmten Selektor reagiert oder nicht.
let canWork = yourObject.respondsToSelector(Selector("image")) // true
Nur wenn dies der Fall ist, funktioniert der Code