NSTableView einstieg

  • NSTableView einstieg

    so, ich bräuchte da mal ein wenig schnelle hilfe. hab mich in den letzten tagen mal ein wenig mit cocoa rumgeschlagen, meine motivation steht aber kurz vor ihrem ende.

    ich versuche mir ein NSTableView mit 2 Spalten zu bauen. Mit einer Spalte war das ganze kein Problem. Ich hab eine neue Klasse erstellt, mit einem Array und den entstprechenden methoden für NSTableView um meine Klasse als dataSource anzugeben. Nun liegt mein Problem bei diesen 2 methoden.

    Ich würde gerne haben, dass mir -(id) tableView: (NSTableView *) tV objectValueForColumn: (NSTableColumn *) tC row: (int) rowIndex; unterscheidet für welche Spalte es einen Wert zurückgibt (aus array1 oder array2). Deshalb hab ich die beiden Spalten im Interface Builder als outlets meiner Klasse definiert.

    1. Bin ich konzeptionell auf einem totalen Holzweg?
    2. Wie mach ich diese unterscheidung? Im sinne von:

    Quellcode

    1. if (meineSpalte == spalteDerMethode) {
    2. return [arrayEins objectAtIndex: rowIndex];
    3. } else {
    4. return [arrayZwei objectAtindex: rowIndex]
    5. }


    Thx, Dominik
    Gruss Dominik.
  • RE: NSTableView einstieg

    Original von deconceptional
    1. Bin ich konzeptionell auf einem totalen Holzweg?

    Ja, vollkommen. Jeder Spalte kannst Du einen Identifier geben (auch im Interface Builder). Der Methode -tableView:objectValueForColumn:row: wird die Spalte mit übergeben und die kannst Du einfach nach ihrem Idendifier fragen. Richtig geschickt wird es, wenn Du diesen Identifier gleich als Key für den Zugriff auf Dein Modell benutzt. Dann brauchst du nicht einmal mehr eine if-Abfrage. Wie das genau geht, findest Du garantiert über die Suche hier im Forum. Es ist schon sehr viel dazu geschrieben worden.

    Michael
  • um michaels antwort zu erweitern:

    man kann wie michael shcon sagte ein dictionary verwenden wo der spaltenidentifier der key ist, man kann aber auch eigene objekte haben und die keys sind die selektoren der anzuwenden methoden.
    also mit der funktion:

    SEL NSSelectorFromString(NSString *aSelectorName)
  • was ist dieser identifier? ein NSString? Sähe das dann mit der if-Abfrage so aus?

    Quellcode

    1. if ([tC idetifier] = @"beispiel") {
    2. return [arrayEins objectAtIndex: rowIndex];
    3. } else {
    4. return [arrayZwei objectAtIndex: rowIndex];
    5. }


    oder:

    Quellcode

    1. if ([tC idetifier] = [meinTableColumnOutlet identifier]) {
    2. return [arrayEins objectAtIndex: rowIndex];
    3. } else {
    4. return [arrayZwei objectAtIndex: rowIndex];
    5. }


    ? Sorry für die dummen Fragen, hab "Programming in Objective-C" und die Apple-Dokumentation gelesen. Viel mehr lag und liegt leider auch in nächster Zeit nicht drin :/

    Thx.
    Gruss Dominik.
  • Tom meint eher so etwas :

    Quellcode

    1. - (id)tableView:(NSTableView*)tv objectValueForTableColumn:(NSTableColumn*)col row:(int)rowIndex {
    2. id theRecord = nil, theValue;
    3. if(tv==tablesamples) theRecord = [samples_record objectAtIndex:rowIndex];
    4. if(tv==tableinstruments) theRecord = [instruments_record objectAtIndex:rowIndex];
    5. if(tv==tablesubsongs) theRecord = [subsong_record objectAtIndex:rowIndex];
    6. if(tv==tablelibs) theRecord = [recordlib objectAtIndex:rowIndex];
    7. if(tv==tableDockIcons) theRecord = [recordDockIcons objectAtIndex:rowIndex];
    8. if(tv==infoSubSongTable) theRecord = [infoSubSongRecord objectAtIndex:rowIndex];
    9. theValue = [theRecord objectForKey:[col identifier]];
    10. return theValue;
    11. }
    Alles anzeigen

    d.h Du hast nicht mehrere Arrays pro Spalte, sondern einen Array der ein Dictionary pro Zeile enthält. Dabei sind die Keys des Dictionarys gleich dem Identifier der Spalten.
    Dabei würdest Du sogar ganz ohne Outlets der Spalten auskommen.

    Sven
    :wq! /dev/null
  • ja aber ich wäre damals froh gewesen wenn mir jemand direkt auf die Finger gekloppt hätte bei einigen Sachen. Dann würde ich heute nicht vor einigen blöden Problemen stehen.

    Und so schwer ist der Brocken nun auch nicht Dictionarys in einem Array zu sortieren.

    Quellcode

    1. sortedArrayUsingFunction:context:
    . Steht sogar in der Apple Doku ein Beispiel dabei.

    Also ich rate ihm da mit den Arrays pro Spalte ab. Das ist viel zu viel Schreibkram.

    Sven
    :wq! /dev/null
  • so, auch ich hab kapiert um was es jetzt genau geht:
    developer.apple.com/documentat…ple_ref/doc/uid/10000026i
    richtig?

    ich hätte da noch eine kleine Frage zum Initialisieren von Objekten:

    Ich hab eine Klasse Controller, die ich im Interface Builder kreiert habe. Ich hab das interafce folgendermassen ergänzt:

    Quellcode

    1. @interface Controller {
    2. ...outlets
    3. NSMutableArray *array;
    4. }
    5. -(id) init;


    dazu meine Implementation:

    Quellcode

    1. @implementation Controller;
    2. -(id) init {
    3. self = [super init];
    4. array = [NSMutableArray array];
    5. return self;
    6. }


    Frage dazu: Wieso muss ich mir mit [array retain] helfen, dass der nicht sofort wieder deallocated wird? Ich hab die Erfahrung gemacht, dass der Array zur laufzeit einfach nicht da ist, wenn ich das nicht mache, das sollte doch nicht so sein? Was mach ich falsch?
    Gruss Dominik.
  • ich hab schon was gelesen über memory-management aber ich hab immer gedacht +init methoden retainen auch automatisch (wird da nicht die alloc-methode aufgerufen)? wohl nicht...

    ok, ich hab noch einen für heute:

    mein Controller hat folgende implementierungen:

    Quellcode

    1. -(id) init {
    2. self = [super init];
    3. dataSource = [[DataSource alloc] init];
    4. [dataSource setDefaults];
    5. [tableView setDataSource: dataSource];
    6. [tableView reloadData];
    7. return self;
    8. }


    und:

    Quellcode

    1. -(IBAction) loadDefaults: (id) sender {
    2. [dataSource setDefaults];
    3. [tableView setDataSource: dataSource];
    4. [tableView reloadData];
    5. NSLog (@"reload data");
    6. }


    Wieso wird NSTableView in der init-methode nicht gefüllt, in der setDefaults aber schon?
    Gruss Dominik.