2010-11-21 7 views
3

Die Zusammenfassung: Ich versuche, eine UITableView als Unteransicht der "Hauptansicht" meines Fensters zu verwenden; wie es scheint, aber wenn ich das Fenster rollen bekomme ich folgende Fehlermeldung:Problem mit UITableView als Unteransicht in einer NIB

2010-11-20 17:17:51.958 xwtf[6997:207] -[NSCFString tableView:cellForRowAtIndexPath:]: unrecognized selector sent to instance 0x5f46550

ich eine Unterklasse von ViewController mit entsprechender NIB-Datei, die durch meine Anwendung delegiert geladen wird. Es ist Ihre typische Vorlage für ein neues Projekt. In dieser NIB-Datei füge ich eine UITableView als Unteransicht der Ansicht hinzu. Im Interface Builder wird die Größe so festgelegt, dass sie das gesamte Fenster einnimmt (d. H. Es überlappt vollständig mit der übergeordneten Ansicht).

Jetzt muss ich eine Datenquelle angeben und delegieren. Ich erstelle eine Klasse namens DumbTableHelper wie so:

@interface DumbTableHelper : NSObject<UITableViewDelegate, UITableViewDataSource> { 
} 

Also, es ist nicht eine Unterklasse von UIViewController, aber ich versuche, diese einfach zu halten - alles was ich brauche ist ein Delegierter und Datenquelle sie rufen können , Recht? Abgesehen von dealloc, meine Methoden in seiner .m-Datei sind:

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 
    return 1; 
} 

- (NSInteger)tableView:(UITableView *)tableView 
numberOfRowsInSection:(NSInteger)section { 
    return 10; 
} 

- (UITableViewCell *)tableView:(UITableView *)tableView 
     cellForRowAtIndexPath:(NSIndexPath *)indexPath { 
    static NSString *CellIdentifier = @"DumbTableCell"; 
    UITableViewCell *cell = [tableView 
          dequeueReusableCellWithIdentifier:CellIdentifier]; 
    if (cell == nil) { 
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault 
            reuseIdentifier:CellIdentifier] 
      autorelease]; 
    } 
    return cell; 
} 

Wie Sie sehen können, bin ich nicht einmal jede Zelle zu konfigurieren; Ich gebe nur 10 Zeilen an, was ausreicht, um das Scrollen zu erzwingen. Jedenfalls ziehe ich in Interface Builder ein Objekt aus der Bibliothek in meine NIB. Ich ändere dann seinen Klassennamen in DumbTableHelper und spezifiziere ihn als Datenquelle und Delegate des UITableView bereits dort. Wenn ich es ausführe, erscheint die Tabelle. Wenn ich versuche, in der Tabelle nach unten zu scrollen, erhalte ich:

010-11-20 18:19:54.673 xwtf[6997:207] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSCFString tableView:cellForRowAtIndexPath:]: unrecognized selector sent to instance 0x5f46550' 
*** Call stack at first throw: 
(
0 CoreFoundation      0x0259eb99 __exceptionPreprocess + 185 
1 libobjc.A.dylib      0x0239340e objc_exception_throw + 47 
2 CoreFoundation      0x025a06ab -[NSObject(NSObject) doesNotRecognizeSelector:] + 187 
3 CoreFoundation      0x025102b6 ___forwarding___ + 966 
4 CoreFoundation      0x0250fe72 _CF_forwarding_prep_0 + 50 
5 UIKit        0x00321d6f -[UITableView(UITableViewInternal) _createPreparedCellForGlobalRow:withIndexPath:] + 619 
6 UIKit        0x00317e02 -[UITableView(UITableViewInternal) _createPreparedCellForGlobalRow:] + 75 
7 UIKit        0x0032c69f -[UITableView(_UITableViewPrivate) _updateVisibleCellsNow:] + 1348 
8 UIKit        0x003247ec -[UITableView layoutSubviews] + 242 
9 QuartzCore       0x0455c481 -[CALayer layoutSublayers] + 177 
10 QuartzCore       0x0455c1b1 CALayerLayoutIfNeeded + 220 
11 QuartzCore       0x045552e0 _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 302 
12 QuartzCore       0x04555040 _ZN2CA11Transaction6commitEv + 292 
13 QuartzCore       0x04585ebb _ZN2CA11Transaction17observer_callbackEP19__CFRunLoopObservermPv + 99 
14 CoreFoundation      0x0257ff4b __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 27 
15 CoreFoundation      0x02514b27 __CFRunLoopDoObservers + 295 
16 CoreFoundation      0x024ddce7 __CFRunLoopRun + 1575 
17 CoreFoundation      0x024dd350 CFRunLoopRunSpecific + 208 
18 CoreFoundation      0x024dd271 CFRunLoopRunInMode + 97 
19 GraphicsServices     0x02d5d00c GSEventRunModal + 217 
20 GraphicsServices     0x02d5d0d1 GSEventRun + 115 
21 UIKit        0x002beaf2 UIApplicationMain + 1160 
22 xwtf        0x00001af4 main + 102 
23 xwtf        0x00001a85 start + 53 
) 

So ist es ruft tableView:cellForRowAtIndexPath: auf .. String? Hat jemand Ideen?

Es tut mir leid, wenn dies eine dumme Frage wird - bisher wurden alle meine Tabellenansichten programmgesteuert von UITableViewController Instanzen erstellt, aber jetzt muss ich eine UITableView als Subview hinzufügen, die nicht dauert den gesamten Bildschirm hoch. Ich habe den Apple-Leitfaden zu Tabellenansichten und Anfang iPhone Development gelesen, um sicherzustellen, dass ich nichts verpasse, aber ohne Erfolg.

Danke!

+0

Ich nehme an, das ist das gleiche Problem wie wenn dieser Fehler auftaucht: '- [CALayer tableView: cellForRowAtIndexPath:]: unerkannter Selektor an Instanz 0x14563c90' gesendet .. dh' CALayer' anstatt 'NSCFString' (aber i könnte schwören, ich habe gesehen, NSCString vor mit dem gleichen Problem kommen) .. honk, wenn Sie 'CALayer 'zu – abbood

Antwort

4

Okay, ich habe herausgefunden, warum: Meine Unterklasse von ViewController, die auch als Dateieigner in meiner NIB-Datei dient, hat keine Steckdose nach DumbTableHelper deklariert. Die Ressourcen Programming Guide auf Nib Dateien auf http://developer.apple.com/library/mac/documentation/cocoa/Conceptual/LoadingResources/CocoaNibs/CocoaNibs.html sagt:

Objekte in der Nib-Datei mit einem behalten erstellt werden Zahl von 1 und Autoreleased dann ... Wenn Sie Steckdosen für nib-Datei Objekte definieren, sollten Sie immer definieren eine Setter-Methode (oder deklarierte Eigenschaft) für den Zugriff auf diesen Ausgang. Setter-Methoden für Outlets sollten ihre Werte beibehalten, und Setter-Methoden für Outlets, die Objekte der obersten Ebene enthalten, müssen ihre Werte beibehalten, um zu verhindern, dass sie freigegeben werden.

Wenn der Tisch zum ersten Mal angezeigt wird, hat die DumbTableHelper noch ein retainCount von 1 und hat noch nicht Autoreleased worden ist, so kann es verwendet werden, um die Reihen zu füllen, die ursprünglich angezeigt werden.Wenn ich scrolle, ist es jedoch nicht mehr im Speicher vorhanden. Aus der Stack-Trace können wir vermuten, dass eine Zeichenfolge in der Speicheradresse zugewiesen wurde, wo die DumbTableHelper verwendet wurde, und so die Nachricht tableView:cellForRowAtIndexPath: fehlerhaft erhält.

Wieder wird das Problem durch einfaches Verbinden einer Steckdose des Dateieigentümers mit der Instanz DumbTableHelper in der Interface Builder-Datei gelöst.

+0

hum .. das ist interessant .. aber ich habe zwei Fragen: 1. man würde annehmen, dass dies ein Problem ist, das automatisch mit ARC gelöst werden sollte (ich schließe aus Ihren alloc dealloc Referenzen, dass dies kein ARC Code ist) .. Sache ist ich * bin * mit ARC, aber ich habe immer noch das gleiche Problem 2. In Ihrem Fall können Sie einfach auf die Datenquelle Steckdose im Storyboard b/c Ihre Datenquelle ist Single und definiert .. was, wenn Sie verwenden eine Datenquelle, die zur Laufzeit definiert ist (was ich mache .. ich benutze den gleichen uitableviewcontroller/tableview mit verschiedenen Datenquellen)? wie gehst du damit um? – abbood

0

Ich empfehle Ihnen, Ihre Verbindungen in Interface Builder zu löschen und zu versuchen, wiederherzustellen. Es scheint, als ob der DataSource-Ausgang mit einem NSString in der Nib verbunden wurde. Sie können auch versuchen, die Verbindung im Code mithilfe der Delegate- und Datenquelleneigenschaften von UITableView herzustellen.

+0

Vielen Dank für die Hilfe CrystalSkull! Nach einigen weiteren Nachforschungen am Nachmittag fand ich den Grund. Die String-Instanz war ein Ablenkungsmanöver, wirklich ... sehe meine Antwort für Details. – shadowmatter

Verwandte Themen