Horizontale Linie in OutlineView

  • Kategorien sind Erweiterungen einer Klasse, Protokolle unabhängig von Klassen, denen man sie dann anhängen muss. Was gemacht wurde, ist eine Kategorie zu NSObject. Dazu gibt es Protokolle, die bedarfsweise angehängt werden.
    Warum weiß ich nicht, hab es erstmal nur blind übernommen.
    8o Das liest sich nach einer Lesestunde.
    I would be embarrassed if they did not spy on me.
  • äh, was jetzt? Angenommen ich hätte das Protokoll und würde conformsToProtocol: verwenden. Dann müsste ich doch wirklich alle Methoden implementieren... So gesehen hast du doch schon Recht, oder nicht? *kopfkratz*

    Ja, wenn man den Beitrag von longW genau liest, rät er dir deshalb davon ab. Also um es klarzustellen: Verwende weder conformsToProtocol: noch <Protocol>.

    Die Deklaration des Protokoles dient allein dem Zweck, die Bezeichner bekannt zu machen.

    Dass es als Kategorie und nicht als Protokoll implementiert ist, hat erstmal nur den Sinn, dass mir das so empfohlen wurde.

    Ich war es jedenfalls nicht.

    Leider gibt es eine ganze Horde von Menschen dort draußen, die nie übre den Unterschied nachgedacht haben. Die verkaufen aber auch ihre Oma. Du solltest deinen Beraterstab wechseln.

    Warum weiß ich nicht, hab es erstmal nur blind übernommen.

    Nicht selbst nachgedacht zu haben, ist keine Ausrede. :)
    Es hat noch nie etwas gefunzt. To tear down the Wall would be a Werror!
    25.06.2016: [Swift] gehört zu meinen *Favorite Tags* auf SO. In welcher Bedeutung von "favorite"?
  • Hi,
    Beraterstab wechseln ist da leider nicht so einfach. *g* Ich hab diesem Jemand auch ne Email geschrieben und nachgefragt. Auch wenn's der Chefentwickler war, er wird mich sicher nicht umbringen. :D

    Der Unterschied ist mir jetzt schon klar, nur scheint ja beides seinen Zweck zu erfüllen. Ob ich nun einfach alle NSObject-Klassen um eine Methode erweitere (die ja aber nicht zwingend implementiert werden muss; wobei, zugegeben, das klingt schon nach Overhead) oder ein Protokoll definiere... letztlich verstehe ich das Argument "Dann kann ja auch ein WebView darauf reagieren" nicht. Das kann es doch so oder so. Das Protokoll sagt ja auch nur "Hallo ihr, wenn ihr mit MyOutlineView kommunizieren wollt, dann solltet ihr diese Methode kennen:" und nicht "Hallo ihr, sofern ihr kein Nachfahre von NSDarfNichtMitOutlineViewKommunizieren seid, zum kommunizieren nutzt halt diese Methode:".

    Nochmal zum Verständnis: das Protokoll, das zu einer Klasse gehört, gibt an, was die Klasse, die gerne mit dieser Klasse kommunizieren will, können sollte oder muss (kommt halt darauf an, wie streng die entsprechende Klasse ist und ob sie auf conformsToProtocol: prüft).
    Dahingegen sind Kategorien Erweiterungen für Klassen. D.h. wenn ich nun eine Kategorie habe

    Quellcode

    1. @interface NSObject (MyCategoryBla)
    2. ...
    3. @end

    ist mein Objekt um all das erweitert, was diese Kategorie angegeben hat. D.h. jede Instanz und jede Subclass von NSObject sollte nun diese neuen Methoden kennen - ob sie nun die entsprechenden Methoden implementiert haben oder nicht, ist dabei ja scheinbar egal, oder wie?

    Hab ich das soweit richtig verstanden?

    Chris
  • Jein

    a) Eine Kategorie bedarf logisch der Implemntierung. Sie hat einfach den Sinngehalt: Für jedes Objekt der Subklassen ist das sinnvoll. Ds bedeutet natürlich nicht, dass es wirklich bei jedem Objekt so sein muss. Aber grundsätzlich ist das denkbar. Vielleicht hast du von meiner unproxy-Methode gelesen, die ich vorein paar Tagen postete: Im Prinzip kann jedes Objekt in einem Binding hängen. Also ist diese Methode für jedes Objekt sinnvoll (prinzipiell): Kategorie von NSObject! (Freilich müssen Kategorien nicht an NSObjekt hängen. Kategorien sind Erweiterungen bestehender Fähigkeiten. Das kann auch nur für NSArray und Subklassen gelten.)

    Wichtig: Eine Kategorie ist typisiert: sie gehört immer zu einer Klasse! Das ist eine strukturelle Frage. Es geht darum, dass Objekte einer bestimmten Klasse etwas können sollen.

    b) Protokolle sind etwas gänzlich anderes. Sie sagen, dass etwas gekonnt werden soll *unabhägig* von der Klasse. Siesind also nicht typisiert. Sie haben zudem keine Implementierung. Sie sind also eine untypisierte äußere Beschreibung.

    Natürlich ähnelt sich das in den Auswirkungn, wenn du eine Kategorie von NSobject machst. Das ist dann aber die Hammerschlagmethode. Natürlich kann es das WebView, *wenn* und *nur wenn* es das Protokoll implementiert, was alleine die Frage es WebViews ist. Bei einer Kategorie kann es das automatisch -- und wird sich ziemlich wundern, was es als Datasource zu tun hat. Dsa meint eben longW mit mangelnder Kapselung. Die Entscheidung des Objektes drückst du ihm auf. Nicht gut!

    Delegates sind konzeptionell gerade untypisierte Helfer, die sich dazu entschlossen haben.

    c) Dass etwa von dem Objekt gekonnt werden muss, ist nur bei formalen Protokollen so. Bei informalen Protokollen geht es um dsa können dürfen!

    Natürlich kannst du sämtliche Funktionalität eines Programmes in einer Subklasse von NSObject implementieren. Das funktioniert. Es ist jedoch nicht sinnvoll.
    Es hat noch nie etwas gefunzt. To tear down the Wall would be a Werror!
    25.06.2016: [Swift] gehört zu meinen *Favorite Tags* auf SO. In welcher Bedeutung von "favorite"?
  • Vielleicht hilft dir meine Implementierung. Ich habe eine Divider Klasse geschrieben, eine subclass von NSCell. Du musst einfach eine Zeile einfügen, die diese Klasse verwendet. Den divider habe ich so gemacht, dass es nach indiehig.com/wiki/Source_Lists#Dividers konform ist.

    Brainfuck-Quellcode

    1. //
    2. // PHFSeperatorCell.h
    3. // Xgrade
    4. //
    5. // Created by Philipe on 18.03.07.
    6. // Copyright 2007 __MyCompanyName__. All rights reserved.
    7. //
    8. #import <Cocoa/Cocoa.h>
    9. @interface PHFSeperatorCell : NSCell {
    10. }
    11. @end
    12. --------------------------------------------------------------------------------
    13. //
    14. // PHFSeperatorCell.m
    15. // Xgrade
    16. //
    17. // Created by Philipe on 18.03.07.
    18. // Copyright 2007 __MyCompanyName__. All rights reserved.
    19. //
    20. #import "PHFSeperatorCell.h"
    21. @implementation PHFSeperatorCell
    22. - (void)drawWithFrame:(NSRect)frame inView:(NSOutlineView *)controlView {
    23. float leftSpace = [controlView indentationPerLevel];
    24. float lineWidth = roundf((leftSpace + NSWidth(frame)) * 0.85);
    25. float lineXPoint = frame.origin.x - leftSpace + roundf(((leftSpace + NSWidth(frame)) - (leftSpace + NSWidth(frame)) * 0.85)/2);
    26. float lineYPoint = frame.origin.y + (NSHeight(frame)/2);
    27. NSRect upperLine = NSMakeRect(
    28. lineXPoint,
    29. lineYPoint,
    30. lineWidth,
    31. 1
    32. );
    33. NSRect lowerLine = NSMakeRect(
    34. lineXPoint,
    35. lineYPoint+1,
    36. lineWidth,
    37. 1
    38. );
    39. // upper line
    40. [[NSColor colorWithDeviceRed:0.82 green:0.85 blue:0.88 alpha:1.0] set];
    41. NSRectFill(upperLine);
    42. // lower line
    43. [[NSColor colorWithDeviceRed:0.98 green:1.0 blue:1.0 alpha:1.0] set];
    44. NSRectFill(lowerLine);
    45. // left cap
    46. // +---+---+-------- - -
    47. // | 1 | 2 |
    48. // +---+---+-------- - -
    49. // | 3 | 4 |
    50. // +---+---+-------- - -
    51. //
    52. // 1:
    53. [[NSColor colorWithDeviceRed:0.87 green:0.89 blue:0.93 alpha:1.0] set];
    54. NSRectFill(NSMakeRect(lineXPoint,lineYPoint,1,1));
    55. // 2:
    56. [[NSColor colorWithDeviceRed:0.84 green:0.87 blue:0.9 alpha:1.0] set];
    57. NSRectFill(NSMakeRect(lineXPoint+1,lineYPoint,1,1));
    58. // 3:
    59. [[NSColor colorWithDeviceRed:0.93 green:0.96 blue:0.99 alpha:1.0] set];
    60. NSRectFill(NSMakeRect(lineXPoint,lineYPoint+1,1,1));
    61. // 4:
    62. [[NSColor colorWithDeviceRed:0.96 green:0.98 blue:1.0 alpha:1.0] set];
    63. NSRectFill(NSMakeRect(lineXPoint+1,lineYPoint+1,1,1));
    64. // right cap
    65. // - - --------+---+---+
    66. // | 1 | 2 |
    67. // - - --------+---+---+
    68. // | 3 | 4 |
    69. // - - --------+---+---+
    70. //
    71. // 1:
    72. [[NSColor colorWithDeviceRed:0.84 green:0.87 blue:0.9 alpha:1.0] set];
    73. NSRectFill(NSMakeRect(lineXPoint+lineWidth-2,lineYPoint,1,1));
    74. // 2:
    75. [[NSColor colorWithDeviceRed:0.87 green:0.89 blue:0.93 alpha:1.0] set];
    76. NSRectFill(NSMakeRect(lineXPoint+lineWidth-1,lineYPoint,1,1));
    77. // 3:
    78. [[NSColor colorWithDeviceRed:0.96 green:0.98 blue:1.0 alpha:1.0] set];
    79. NSRectFill(NSMakeRect(lineXPoint+lineWidth-2,lineYPoint+1,1,1));
    80. // 4:
    81. [[NSColor colorWithDeviceRed:0.93 green:0.96 blue:0.99 alpha:1.0] set];
    82. NSRectFill(NSMakeRect(lineXPoint+lineWidth-1,lineYPoint+1,1,1));
    83. }
    84. @end
    Alles anzeigen


    Hoffe das hilft.