Anfängerfrage zu Klassenattributen

  • Anfängerfrage zu Klassenattributen

    Hallo zusammen.

    In anderen objektorientierten Sprachen kann ich "Klassenattribute" anlegen, d.h. Attribute, die nicht an der Instanz sondern an der Klasse selbst hängen. Man kann von jeder Instanz bzw. auch der Klasse darauf zugreifen. Genau diese Eigenschaft vermisse ich bzw. habe ich in der Doku nicht gefunden.
    Es gibt den "Würgaround" des Singletons, was ich persönlich als "Kanone, die auf Spatzen schießt" ansehen würde.

    Stimmt es, dass es keine Klassenattribute im oben genannten Sinne gibt?

    Vielen Dank für Eure Antworten!
  • RE: Anfängerfrage zu Klassenattributen

    Meinst du so etwas wie

    Quellcode

    1. static NSUInteger numberOfSubClasses;
    ?
    Gibt es sicherlich, ist ja irgendwo auch nur C. Ich weiß nur nicht, wofür man das gebrauchen kann.
    Wofür brauchst du das?
    «Applejack» "Don't you use your fancy mathematics to muddle the issue!"

    Iä-86! Iä-64! Awavauatsh fthagn!

    kmr schrieb:

    Ach, Du bist auch so ein leichtgläubiger Zeitgenosse, der alles glaubt, was irgendwelche Typen vor sich hin brabbeln. :-P
  • RE: Anfängerfrage zu Klassenattributen

    Du kannst das mit static machen.

    Hier mal ein Beispiel:

    Quellcode

    1. + (id)sharedInstance {
    2. static MyClass *sharedInstance = nil;
    3. if (sharedInstance == nil) {
    4. sharedInstance = [[MyClass alloc] init];
    5. }
    6. return sharedInstance;
    7. }
    Windows, nein danke...
  • Daten, die nur einmal eingelesen werden sollen (Customizing) und sich im Anschluss nicht mehr ändern, werden in objektorientierten Sprachen normalerweise direkt an der Klasse gespeichert und nicht mehrfach in den Objekten. Alle Objekte arbeiten somit mit dem gleichen Klassenattribut.
    Ich brauche es um eine Propertylist für alle Instanzen der Klasse verfügbar zu machen. Sie soll nur einmal gelesen werden und dann immer wieder von diesen Instanzen benutzt werden. Ich weiß, dass man sowas mit Singletons (siehe Beispiel von Clemens) machen kann, empfinde es aber als umständlich.


    Noch eine Frage zu dem Beispiel von Clemens:
    Wie deallociere ich denn am Ende eine static-Variable, die doch nur in dieser Methode zur Verfügung steht? Ich habe doch hier ein Memoryleak oder liege ich da falsch?
  • Klassenattribute in der beschriebenen Form sieht Objective-C nicht vor. Die vorgestellten Maßnahmen sind im Prinzip Umwege, um das trotzdem zu erreichen.
    Freigeben kannst Du eine 'static' deklarierte Variable nicht. Die sog. "leaks" beziehen sich auf Instanzen, die nicht freigegeben werden. Dazu sind in den Wurzelklassen und deren Protokollen die Methoden zur Speicherverwaltung vollständig implementiert.
    I would be embarrassed if they did not spy on me.
  • Auf die Gefahr hin, das ich gleich erschlagen werde, aber ich hatte das selbe "Problem".
    Ich habe es über die App-Delegate gelöst, weil mir das mit den statics irgendwie zu doof war ;)

    In der delegate Headerdatei habe ich:

    @interface xxxAppDelegate...
    {
    NSString *pagePath;
    ...
    }

    @property (nonatomic, retain) NSString *pagePath;

    In der m datei:
    @syntesize pagePath;

    Und aus irgendeiner Datei greife ich dann mit:

    MyAppDelegate *appDelegate = (MyAppDelegate *)[UIApplication sharedApplication].delegate;

    appDelegate.pagePath = blubblab; // pagePath bekommt nen wert
    blubla = appDelegate.pagePath; // pagePath verwenden


    Funktioniert. Zwar bestimmt total umständlich und geht evtl. auch einfacher, aber nach 3 Wochen Objective-C ist nicht mehr drin ;)
  • Vielen Dank für die vielen schnellen und qualifizierten Antworten.

    Ich fasse zusammen:
    es gibt in Obj. C keine Klassenattribute. Wenn man sowas braucht muss man auf das Singletonpattern mit Static-Variablen zurückgreifen.
    Die Lösung über die Application gefällt mir persönlich nicht so, da das Kapseln der Daten nicht gegeben ist.
  • Original von Metro
    Vielen Dank für die vielen schnellen und qualifizierten Antworten.

    Ich fasse zusammen:
    es gibt in Obj. C keine Klassenattribute. Wenn man sowas braucht muss man auf das Singletonpattern mit Static-Variablen zurückgreifen.
    Die Lösung über die Application gefällt mir persönlich nicht so, da das Kapseln der Daten nicht gegeben ist.

    Ich will es etwas anders formulieren:

    Es gibt keine Klassenattribute, weil Klassen Schablonen für Instanzen sind. Wer Klassenattribute haben will, der will eigentlich einen Singleton. Deshalb ist es eigentlich schlicht richtig, es über das Singletonpattern zu machen. Es ist halt unbequemer.
    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"?
  • Hallo Amin,

    wenn ich ein Klassenattribut haben will, muss ich nicht unbedingt ein Singleton haben wollen.

    Wenn Du Dir das Designpattern "Singleton" anschaust, wird es verwendet um eine Referenz auf ein Objekt zu haben, das nur 1x instanziiert werden kann.

    Ein Klassenattribut hat eine andere Ausrichtung: Hier habe ich eine "Variable", die es nur 1x für alle Instanzen gibt. Diese Variable braucht keine Referenz auf eine Instanz sein.


    Es kann auch zum Beispiel ein Integer sein:

    Im Prinzip funktioniert es so wie bei "release/retain". Eine Variable vom Typ Integer wird hoch- bzw. runter gezählt. Sie hält den Wert für alle Instanzen, die von dieser Klasse abstammen. Nur diese Instanzen können ggf. darauf zugreifen, wenn es sich um ein privates Klassenattribut handelt.

    Insofern fehlt dieses Sprachelement hier, was man aber durch das Singleton-Pattern umgehen kann.
  • Mal ganz davon abgesehen, dass ich den Sinn hinter diesem Gezähle nicht verstehe, würde das hier funktionieren oder gibt das auch nur Instanzattribute?

    Quellcode

    1. static int _count = -1;
    2. -(id)init {
    3. self = [super init];
    4. if(self) {
    5. if(_count == -1) {
    6. _count = 1;
    7. } else {
    8. _count++;
    9. }
    10. }
    11. }
    12. -(void)dealloc {
    13. _count--;
    14. [super dealloc];
    15. }
    Alles anzeigen


    Der Retain-Count ist übrigens instanzgebunden, alles Andere wäre ja auch Schwachsinn.

    Was genau willst du mit diesem Klassenattribut denn realisieren?
    Vielleicht ist dein Ansatz einfach nur 'nicht ObjC konform'. ;)
    «Applejack» "Don't you use your fancy mathematics to muddle the issue!"

    Iä-86! Iä-64! Awavauatsh fthagn!

    kmr schrieb:

    Ach, Du bist auch so ein leichtgläubiger Zeitgenosse, der alles glaubt, was irgendwelche Typen vor sich hin brabbeln. :-P
  • Original von Metro
    Hallo Amin,

    wenn ich ein Klassenattribut haben will, muss ich nicht unbedingt ein Singleton haben wollen.

    Keine Ahnung, was du willst. Du hast aber einen.

    Eine Klasse ist ein Entitätstyp. Der hat keine konkreten Werte. Konkrete Werte hat nur eine Entität.

    Wenn man jetzt nur eine Entität von einem Entitätstypen hat, kann man sich die Sache einfach machen und einfach die Eigenschaften der Entität an den Entitätstypen kleben, ist ja eine 1-zu-1-Beziehung. Das ändert aber nichts daran, dass du logisch eine Entität und einen Entitätstypen hast. Deshalb ist der "ausformulierte" Singleton einfach die bessere, aber unbequemere Abbildung.

    Original von Metro

    Wenn Du Dir das Designpattern "Singleton" anschaust, wird es verwendet um eine Referenz auf ein Objekt zu haben, das nur 1x instanziiert werden kann.

    Ein Klassenattribut hat eine andere Ausrichtung: Hier habe ich eine "Variable", die es nur 1x für alle Instanzen gibt. Diese Variable braucht keine Referenz auf eine Instanz sein.

    Ich weiß nicht, wie man das implementiert, da ich noch nie programmiert habe. Ich weiß aber, dass Entitätstypen keine Attribute haben.

    Original von Metro

    Es kann auch zum Beispiel ein Integer sein:

    Im Prinzip funktioniert es so wie bei "release/retain". Eine Variable vom Typ Integer wird hoch- bzw. runter gezählt. Sie hält den Wert für alle Instanzen, die von dieser Klasse abstammen. Nur diese Instanzen können ggf. darauf zugreifen, wenn es sich um ein privates Klassenattribut handelt.

    Das sieht jetzt eigentlich mehr wie ein Twintone aus. Egal.

    Original von Metro
    Insofern fehlt dieses Sprachelement hier, was man aber durch das Singleton-Pattern umgehen kann.

    Das Sprachelement fehlt, weil es die bequemere, jedoch unsauberere Formulierung ist.
    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"?
  • Das klingt jetzt vielleicht ein bisschen achtmalklug, aber
    ist nicht jede Klasse in Objective-C auch ein Objekt?

    Ein Klasse hat doch auch einen "isa" Pointer und wenn ich eine Nachricht
    an eine Klasse schicke, schicke ich ich diese doch an ein Klassenobjekt!?

    Und dann hätte eine Klasse meines Erachtens auch Instanzvariablen.

    Oder ist dies nur eine verwirrte Auffassung?

    Ich erinnere mich dunkel an Metaklassen in Smalltalk...
    Ewig erstaunt...
  • Ja, aber offenkundig keine Entität. Du hast natürlich "Metaattribute", so wie ein Entitätstyp auch wieder eine Entität eines "Entitätstyptypen" ist. Aber das programmierst du ja nicht.

    Die Abbildung – in Objective-C, C++ usw. – ist so, dass eine Instanz eine Entität darstellen soll und die Klasse den Entitätstypen. Von diesem Konzept ausgehen, können Klassen in der Programmiersprache keine konkreten Werte haben. Sie können nur mittels Konstanten beschreiben, was eine Entität ist.

    Das Laufzeitsystem modelliert auch so etwas ähnliches, nämlich Metaklassen. Das Verhältnis zwischen Metaklassen und Klassen ist jedoch 1-zu-1, weil mangels Klassenattributen keine Unterscheidungen zwischen den "Instanzen der Metaklassen" geben kann. Die Klasse ist also sozusagen wieder der Singleton der Metaklasse.
    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"?
  • Original von AndreasA
    Das klingt jetzt vielleicht ein bisschen achtmalklug, aber
    ist nicht jede Klasse in Objective-C auch ein Objekt?

    Ein Klasse hat doch auch einen "isa" Pointer und wenn ich eine Nachricht
    an eine Klasse schicke, schicke ich ich diese doch an ein Klassenobjekt!?

    Und dann hätte eine Klasse meines Erachtens auch Instanzvariablen.

    Oder ist dies nur eine verwirrte Auffassung?

    Ich erinnere mich dunkel an Metaklassen in Smalltalk...


    Nein, eine Klasse ist quasi nur die Bauanleitung wie eine Instanz gebaut wird!
  • Die Abbildung – in Objective-C, C++ usw. – ist so, dass eine Instanz eine Entität darstellen soll und die Klasse den Entitätstypen. Von diesem Konzept ausgehen, können Klassen in der Programmiersprache keine konkreten Werte haben. Sie können nur mittels Konstanten beschreiben, was eine Entität ist.


    Ja, das entspricht eigentlich auch meinem Gedankenmodell, wenn ich programmiere.



    Ich habe dennoch meinen Gedanken das eine Klasse ein Objekt einer Metaklasse ist,
    mal weiterverfolgt und bin dabei auf folgendes gestossen. Ich finde es zumindest
    eine interessante Betrachtung.

    sealiesoftware.com/blog/archiv…sses_and_metaclasses.html
    Ewig erstaunt...
  • Eine Klasse meint ein Klassenobjekt, ein Objekt ein Instanzobjekt.
    Was sollen da Metaklassen?

    Übrigens braucht doch eh keiner so etwas Sinnloses wie Klassen.
    Naja, Smalltalk, ObjC, C#, PHP, ObjJ und C++ vielleicht. ;)
    «Applejack» "Don't you use your fancy mathematics to muddle the issue!"

    Iä-86! Iä-64! Awavauatsh fthagn!

    kmr schrieb:

    Ach, Du bist auch so ein leichtgläubiger Zeitgenosse, der alles glaubt, was irgendwelche Typen vor sich hin brabbeln. :-P
  • Original von Lucas de Vil
    Eine Klasse meint ein Klassenobjekt, ein Objekt ein Instanzobjekt.
    Was sollen da Metaklassen?

    Übrigens braucht doch eh keiner so etwas Sinnloses wie Klassen.
    Naja, Smalltalk, ObjC, C#, PHP, ObjJ und C++ vielleicht. ;)



    Kann man eigentlich irgendwo Software-Filosofie studieren?
    Ewig erstaunt...