Globale Variablen

zorn

Zuccalmaglios Renette
Registriert
18.02.06
Beiträge
260
Hallo,

eine wahrscheinlich *sehr* bescheuerte Frage:

Sagen wir ich habe eine Applikation die aus 10 Klassen besteht. Ich möchte eine Variable definieren die in allen Klassen mit allen Rechten verfügbar ist. Wie mache ich das?
Muss ich also diese Klasse, in der die Variable definiert wird in allen anderen importieren?
Sagen wir es geht um den Wert eines DropDown Feldes, der überall verfügbar sein soll.

Wie schon gesagt, wahrscheinlich saublöd, bin Anfänger...
 

freddy.duese

Bismarckapfel
Registriert
05.11.05
Beiträge
146
Ohne zu wissen in welcher Sprache du programmierst ist es etwas schwierig. In Java, C++ oder Ähnlichem könnte man dein Problem mit einem Singleton lösen.
Meist ist es aber ein Zeichen von schlechtem Design wenn man auf globale Variablen angewiesen ist.
Eventuell solltest du deinen Ansatz überdenken.
 

zorn

Zuccalmaglios Renette
Registriert
18.02.06
Beiträge
260
Es ging um Objective-C - sorry...
Ich folge deinem Rat und überdenke mein Design. Wenn ich den Überblick richtig verstanden habe glaube auch schon eine Lösung gefunden zu haben: Bindings (koool)

Die Apple Technologien sind unglaublich praktisch. Bin gespannt was noch so kommt 8)
 

MatzeLoCal

Rheinischer Bohnapfel
Registriert
05.01.04
Beiträge
2.422
Singleton war schon das richtige Stichwort... und auch hierzu gibt die Doku von Apple was her :)

Singleton bedeutet übrigens nicht schlechtes Design.... es kann ein Auswuchs davon sein... aber das kann fast alles sein ;)
 

Amin Negm-Awad

Süsser Pfaffenapfel
Registriert
01.03.07
Beiträge
665
Bleibt nur noch zu erwähnen, dass der Apple-Vorschlag unnnötig eine globale Variable verwendet:
Code:
+ (MyClass*)sharedInstance { // oder ein anderer Name, der sinnvoll ist
    static MyClass* sharedInstance = nil; // Genau so!

    if( !sharedInstance ) {
        sharedInstance = [[MyClass alloc] init]; // Singletons werden nicht mehr freigegeben.
    }

    return sharedInstance;
}

Rodewig/Negm-Awad, Objective-C und Cocoa, 2. Auflage, Seite 567
 
Zuletzt bearbeitet:

Senior Sanchez

Damasonrenette
Registriert
08.09.06
Beiträge
491
Ehm, ich bin noch nicht so der Objective-C Experte, aber Amin, ist dein Code da nicht falsch?

Bei jedem Aufruf von sharedInstance erzeugste doch ein neues Objekt, weil du doch sharedInstance jedesmal auf nil setzt, oder?

Und das ist denke ich nicht der Sinn von Singletons.
 

MacApple

Schöner von Bath
Registriert
05.01.04
Beiträge
3.652
Bei jedem Aufruf von sharedInstance erzeugste doch ein neues Objekt, weil du doch sharedInstance jedesmal auf nil setzt, oder?
Nein, das Schlüsselwort "static" bewirkt, dass die Variable nur beim ersten Aufruf der Methode auf 'nil' gesetzt wird. Statische Variablen bleiben dann für den Rest der Programmlaufzeit so im Speicher. Deshalb behält die lokale Variable auch ihren Wert über das Ende der Methode hinaus, d.h. beim zweiten und jedem weiteren Aufruf der Methode zeigt die statische lokale Variable immer noch auf das im ersten Aufruf erzeugte und zugewiesene Objekt.

MacApple
 

Senior Sanchez

Damasonrenette
Registriert
08.09.06
Beiträge
491
Nein, das Schlüsselwort "static" bewirkt, dass die Variable nur beim ersten Aufruf der Methode auf 'nil' gesetzt wird. Statische Variablen bleiben dann für den Rest der Programmlaufzeit so im Speicher. Deshalb behält die lokale Variable auch ihren Wert über das Ende der Methode hinaus, d.h. beim zweiten und jedem weiteren Aufruf der Methode zeigt die statische lokale Variable immer noch auf das im ersten Aufruf erzeugte und zugewiesene Objekt.

MacApple

Aso, diese besondere Bedeutung von static kannte ich noch nicht.

Ich bin halt java gewohnt und da ist das eben anders ;)

Danke für die Aufklärung
 

freddy.duese

Bismarckapfel
Registriert
05.11.05
Beiträge
146
In Java ist das meines Erachtens genau so.
Da kann man statische Variablen auch zum Instanzen Zählen verwenden.
 

Amin Negm-Awad

Süsser Pfaffenapfel
Registriert
01.03.07
Beiträge
665
Deshalb hatte ich ja auch extra "Genau so" kommentiert. Du benötigst das static. Es erzeugt vor einer einer lokalen Variable den gewohnten lokalen Scope, jedoch globalen Extent.

Wie es in Java ist, kann ich nicht sagen.
 

Senior Sanchez

Damasonrenette
Registriert
08.09.06
Beiträge
491
In Java ist das meines Erachtens genau so.
Da kann man statische Variablen auch zum Instanzen Zählen verwenden.

Nope, ist es nicht.

In einer Methode lassen sich in Java schonmal keine statischen Attribute definieren. Das geht nur in der Klassendefinition.

In Java würde das so aussehen.

Code:
private static MyClass instance = null;

public static MyClass sharedInstance() {
  if(instance == null) instance = new MyClass();

  return instance;
}

Aber ich verstehe schon. Durch diese static Deklaration im Objective-C Code spart man sich einfach ne globale Variable.
 

Amin Negm-Awad

Süsser Pfaffenapfel
Registriert
01.03.07
Beiträge
665
Wobei es bei der Ersparnis weniger um den ersparten Code geht -- dieser ist sogar länger. Aber man kapselt das sauberer und hat damit letztlich so etwas wie Klassenvariablen in Java.

Das ist einfach sauberer als Apples Lösung.
 

tjp

Altgelds Küchenapfel
Registriert
07.07.04
Beiträge
4.057
Bleibt nur noch zu erwähnen, dass der Apple-Vorschlag unnnötig eine globale Variable verwendet:
Nein, das Apple Design ist flexibler, da die Lösung von Apple erlaubt während der Laufzeit des Programms das Singleton mehrmals zu erzeugen und zu zerstören (wenn man die Klasse entsprechend erweitert). Die Lösung über die statische Variable in der Methode erlaubt es nur das Objekt zur Laufzeit zu Erzeugen, ein kontrolliertes Zerstören des Objekts ist nicht möglich, da man keinen Zugriff auf Objektzeiger hat.
 

Amin Negm-Awad

Süsser Pfaffenapfel
Registriert
01.03.07
Beiträge
665
Deine Aussage ist schlicht falsch.

Bereits wenig anspruchsvoller Code zeigt dies
Code:
+ (MyClass*)sharedInstanceCreateNew:(BOOL)creationRequet {
    static MyClass* sharedInstace = nil;

    // Alwways create the first instance
    if( !sharedInstances ) {
       // wie gehabt
        …

    } else if( creationRequest )
         [sharedInstacne release];
         // wie gehabt zur Neuerzeugung
         …
   }

   return sharedInstance;
}

+ (MyClass*)sharedInstance {
    return [self sharedInstanceCreateNew:NO];
}
 
Zuletzt bearbeitet:

tjp

Altgelds Küchenapfel
Registriert
07.07.04
Beiträge
4.057
Bereits wenig anspruchsvoller Code zeigt dies
Durch das Auge auf die Brust - man kann auch an Dogmatismus sterben. Die Lösung ist absolut ungewöhnlich und krankt an dem Problem, daß man nun unterschiedlichen Methoden-Semantik für zerstörbare Singletons und nicht-zerstörbare Singletons hat. Sauberes Design ist etwas anderes.
 

Amin Negm-Awad

Süsser Pfaffenapfel
Registriert
01.03.07
Beiträge
665
Durch das Auge auf die Brust - man kann auch an Dogmatismus sterben. Die Lösung ist absolut ungewöhnlich und krankt an dem Problem, daß man nun unterschiedlichen Methoden-Semantik für zerstörbare Singletons und nicht-zerstörbare Singletons hat. Sauberes Design ist etwas anderes.
a) Die Lösung ist nicht ungewöhnlich, sondern allenfalls dir unbekannt.
b) Es ist sauberes Design, einen Singleton an genau einer Stelle zu erzeugen und zu "vernichten". (Wirklich vernichtet wird ein Singleton in der Regel nicht.)
c) Wer nicht zerstören will, benutzt einfach -sharedInstance. Da ist gar nichts anders.
d) Selbstverständlich kann auch -sharedInstance selbst entscheiden, ob es neue Objekte herstellt. Etwa in den Fällen, in denen das nicht vo außen beeinflusst werden soll.
e) Deine Antwort hat nichts mit deinem Beitrag zu tun. Der lautete:
Die Lösung über die statische Variable in der Methode erlaubt es nur das Objekt zur Laufzeit zu Erzeugen, ein kontrolliertes Zerstören des Objekts ist nicht möglich, da man keinen Zugriff auf Objektzeiger hat.
Ich kann nicht erkennen, was daran durch deinen neuerlichen Beitrag richtig geworden sein sollte.

Danke für die Diskussion.
 

tjp

Altgelds Küchenapfel
Registriert
07.07.04
Beiträge
4.057
a) Die Lösung ist nicht ungewöhnlich, sondern allenfalls dir unbekannt.
Sie ist ungewöhnlich, da sie weitere überflüssige Parameter für eine Methode einführt. "static" Variablen in einer Übersetzungeinheit sind lokal zu dieser und außerhalb dieser Übersetzungeinheit nicht sichtbar. Man verunreinigt mit der Apple-Lösung daher nicht den globalen Namensraum, da Apple immer empfiehlt pro Klasse eine Übersetzungseinheit zu verwenden. Aus diesem Grund ist das Geheimnisprinzip für die betreffende Singleton-Klasse gewahrt. Apple ordne ich in diesem Punkt ein höhere Kompetenz zu als euch beiden.
 

zorn

Zuccalmaglios Renette
Registriert
18.02.06
Beiträge
260
Ok - aber nur interessahalber:

wie kann ich in ein als @public deklariertes Array einen Wert adden?

mal angenommen:

@public
NSMutableArray *blubber;

Wie weise ich blubber einen Wert zu? Ich hab' das standardmässig ala 'blubber = [blabla blalba]' versucht, und erhalte nur eine Warnung dass eine lokale deklaration die Instanzvariable überschreibt. Aber wie dann? Aus der Apple Doku 'ceo->boss = nil' werd' ich nicht schlau. Da steht auch noch der Hinweis dass man Inforamtionen in Instanzvariablen stored indem ein anderes Objekt eine Message zur Variable schickt. Ich steh' auf dem Schlauch...
 

Peter Maurer

Pommerscher Krummstiel
Registriert
16.03.04
Beiträge
3.077
Sie ist ungewöhnlich ...
Das Wort "un/gewoehnlich" sagt ja was ueber Haeufigkeit aus, deshalb zur Info: Ich mach' das auch oft so, und zwar mit Vorliebe in dieser Form:

Code:
+ (PMNiftyObject*)sharedNiftyObjectByForcingRecreation: (BOOL)recreate {
	static PMNiftyObject *singletonNiftyObject = nil;
	if (recreate && (singletonNiftyObject)) {
		[singletonNiftyObject release];
		singletonNiftyObject = nil;
	}
	if (!singletonNiftyObject) {
		singletonNiftyObject = [[PMNiftyObject alloc] init];
		// weitere Initialisierung bei Bedarf
	}
	return singletonNiftyObject;
}
Deshalb: Du magst die Methode bescheuert finden, aber so ungewoehnlich ist sie vielleicht gar nicht. :)