Wie cached die UITableView?

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • Wie cached die UITableView?

    Die UITableView cached ja die Zelltypen, die man in ihr anzeigt. Man kann sich diese über die Methode holen:


    Quellcode

    1. - (UITableViewCell *)dequeueReusableCellWithIdentifier:(NSString *)identifier


    Mich würde interessieren, wie die TableView das intern löst. Ich hab mal in den header geschaut. Dort gibt es ein MutableDictionary

    Quellcode

    1. NSMutableDictionary *_reusableTableCells;


    Hier wird für jeden identifier wohl eine Zelle gespeichert. Ich frage mich nur wie ich dann diese einzelne Zelle mit unterschiedlichem Inhalt füllen kann.

    Daher habe ich mal ein Testprojekt gemacht und hier eine Subclass einer UITableViewCell erstellt und dort alle Methoden überschrieben und per NSLog ausgegeben. Es zeigte sich, dass es bei drei Zeilen meiner Zelle auch drei Objekte dieser Zelle gibt. Eigentlich hatte ich erwartet, es gibt nur ein Objekt. Das dequeue soll also nur sich wiederholende allocs vermeiden. Aber wie? Ich mein wenn in dem Dict nur ein Objekt ist, wie macht man dann resourcensparend 3 daraus? copy ist ja genau so schlimm wie alloc. Hat da jemand Ideen?

    Hintergrund: ich möchte eine GridView bauen, die nach dem selben Prinzip nur Informationen über sichtbare Zellen merkt und Zelltypen cachen kann.

    Hat da jemand ne Idee, wie man das machen könnte?
  • Wieviele Instanzen erzeugt werden hängt einzig und allein davon ab, was Du in

    Quellcode

    1. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

    zurückgibst. Instanziierst Du da jedes mal eine neue Zelle hast Du viele, nutzt Du da das dequeueReusableCellWithIdentifier: und erzeugst nur eine neue Instanz Deiner Zelle, wenn da nil zurückkommt, dann hast Du eine Instanz.
    if (!exit(-1)) fprintf(stderr, "exit call failed. Program will continue\n");
  • Darf man jetzt über das SDK reden?

    Du kannst ein GridView auch mit UITableView implementieren. Du kannst ja einfach eine eigene UITableViewCell erzeugen (Subclassing) und diese Cell in mehrere Spalten unterteilen...

    Ein paar Worte zum Caching:
    Hintergrund ist z.B folgender: Angenommen du hast ein TableView, welches Ordner und Dateien angzeigt. Für Ordner hast du eine OrdnerCell Klasse und für Dateien hast du eine Klasse DateiCell. Beide subclassen UITableViewCell.

    Falls du nun in:

    Quellcode

    1. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath


    anhand von indexPath.row feststellst, dass du einen Ordner anzeigen sollst, dann erzeugst du dir eine OrdnerCell. Falls du aber schon eine OrdnerCell hast, dann kannst du ja einfach diese nutzen. Gleiches gilt für DateiCells. Gleichartige Cells sollte man nicht mehrmals erzeugen.

    Intern würde ich sowas über Core Animation lösen. UIViews sind im Gegensatz von NSViews fest mit einem Layer verbunden. NSVies können einen Layer haben und UIViews haben garantiert einen. Du kannst also (falls du ein eigenes UITableView/GridView schreiben willst) dir die erzeuge Cell geben lassen, dir den Layer holen und diesen anzeigen - anstelle des Views. Dass das MouseTracking dennoch simpel funktioniert kann dein UITableView die Events einfach an das entsprechende UITableViewCell weiterleiten.
    Die Objective-Cloud ist fertig wenn sie fertig ist. Beta heißt Beta.

    Objective-C und Cocoa Band 2: Fortgeschrittene
    Cocoa/Objective-C Seminare von [co coa:ding].
  • Vielen Dank für die Antworten!
    Mir ist schon klar wie man TableViews bedient ;)

    das mit den CoreAnimation layers war ein guter Hinweis, daran hatte ich such schon gedacht. Allerdings werden die Cells tatsächlich als subview der tableView gesetzt. Es sind also nicht nur die Layer.

    Das ganze mit einer TableView zu machen geht natürlich. Allerdings will ich, dass die einzelnen Elemente beweglich sind.
  • Dass das MouseTracking dennoch simpel funktioniert kann dein UITableView die Events einfach an das entsprechende UITableViewCell weiterleiten.

    Mousetracking??? ;)

    Wenn dein Grid View nur einen Typ von Zellen hat, könntest du einfach einen NSMutableArray für die "reusableCells" erstellen. Zellen, die nicht mehr sichtbar sind, werden da reingeschmissen, wenn neue gebraucht werden, holt der View sie aus dem Array und setzt den Inhalt neu. Bei mehreren verschiedenen Typen kannst du natürlich auch ein NSMutableDictionary verwenden (Keys sind die reuseIdentifier), das jeweils solche Queues (Arrays) enthält.

    Eine Warnung vorweg: UIScrollView zu subclassen (worauf es bei dir dann wahrscheinlich hinausläuft) ist nicht gerade, was ich ein Vergnügen nennen würde... Insofern würde ich mir vorher wirklich genau ansehen, ob es sich nicht doch mit einem UITableView lösen lässt. Wenn du einzelne Zellen nur entweder innerhalb einer Zeile oder nur ganze Zeilen verschieben willst, sollte es sich damit machen lassen.
  • hey omz, genau so wie du es gesagt hast, funktioniert es tatsächlich fast am besten.
    nur dass man keine arrays benutzt sondern NSSets, weil die reihenfolge ja egal ist.

    UIScrollView zu subclassen ist kein problem. dafür ist die ja da?!?

    wie ist das nun eigentlich mit dem NDA? ist der noch in kraft? wäre ja irgendwie denkbar dämlich.
  • Das SDK ist unter NDA. Eigentlich habe ich keine Lust damit anzufangen die Threads zu schliessen, oder gleich das iPhone Board. High Level übers iPhone reden ok, aber sobald irgendwo ein UI vorne dransteht, muss ich als Forenbetreiber die Notbremse ziehen. Also hört damit auf über das SDK zu schreiben. Danke. Das ist übrigens der 100ste Hinweis dazu.