Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

Karim

Frischling

  • »Karim« ist der Autor dieses Themas

Beiträge: 7

Wohnort: Düsseldorf

  • Private Nachricht senden

1

19.09.2014, 12:41

[Objective-C 3.0] Properties & Instanzvariablen (Zugriff etc.)

Halli Hallo,

ein weiteres mal...ich hoffe ich störe mit meinen Fragen ein letztes Mal, aber aller Anfang ist schließlich schwer :D
Ich bin weiterhin am Objective-C 3.0 programmieren und lernen und habe mich jetzt schon ein ganzes Stück mit Properties und co. beschäftigt.
Allerdings hackt es irgendwo bei mir ein wenig, irgendwas schmeiße ich da - so glaube ich - durcheinander, langsam bin ich verwirrt.

Eine Property kann ich öffentlich in der .h Datei der Klasse oder privat in einem privaten Interface in der .m Datei erzeugen. Bei letzterem kann ich im öffentlichen Interface dann sagen, inwieweit die Property, welche vorher in der privaten .m Datei angelegt wurde, zugegriffen werden darf (zum Beispiel mit readonly, um den Wert einer Property auszulesen).

Durch das erzeugen einer eigenen Property (nennen wir sie im Folgenden einfach mal "Level") erzeugt XCode automatisch eine Getter und Setter Methode, sowie eine Instanzvariable.

Um nun IN DER DEKLARATION (sprich vor allem in der .m Datei) auf die Property zuzugreifen, mache ich dies über "self.level = 10" (als Beispiel), richtig?
Um nun auf die Instanzvariable, welche automatisch angelegt wurde, direkt zuzugreifen, nutze ich "_level = 10", richtig?

Meine Frage und Verwirrung: Wann sollte ich auf die Property und wann auf die Instanzvariable direkt zugreifen? Ist da ein Unterschied oder ist das egal?

Wenn ich nun einen Initialisierer schreibe, sähe der so aus:

- (id) initWithLevel: (int) level { self = [super init] if (self) { _ level = level; }return self }


In dem If-Block greife ich nun ja auf _level, also direkt auf die Instanzvariable zu. Könnte ich auch theoretisch über "self.level" auf die Property zugreifen?
Macht das überhaupt einen Unterschied oder ist das egal?


Um nun in der main.m auf die Methode zuzugreifen nutze ich ja "[MeineKlasse meineMethode]".
Um dort aber auf die Property bzw. dessen Variable, die zum Beispiel den Level speichert, zuzugreifen nutze ich "meinObjekt.level = 10" richtig?
Alternativ könnte ich auch die von X Code selbst erzeugte Setter Methode aufrufen, um dem Objekt einen Wert zuzufügen...

Damit ich nun aber bei meinem Objekt nicht immer "meinObjekt.Property = x" schreiben muss, baue ich einen Initialisierer, wo ich quasi alles direkt in einem Abwasch eingeben kann, oder?

Wie dem auch seie, meine Hauptfrage geht eben auf die Instanzvariable und Property zurück. Ich bin vor allem verwirrt, wann und wieso ich auf die Property und wann auf die Instanzvariable zugreifen soll. Im Endeffekt wird doch bei beidem der selbe Wert gleich gespeichert, oder?
Warum sollte bzw. kann ich darüberhinaus noch weitere Instanzvariablen, ohne das Erzeugen eines Properties, anlegen?

Ich bin leicht verwirrt, sorry dafür und danke für die Hilfe im Voraus!

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Karim« (19.09.2014, 12:58)


spintop

Frischling

Beiträge: 1

Wohnort: Berlin

  • Private Nachricht senden

2

21.09.2014, 13:26

Hey :)

in deinem Fall wäre "meinObjekt.property = 10;" äquivalent zu "[meinObjekt setProperty:10];". Die erstere Schreibweise ist lediglich syntax sugar und dient damit nur der Vereinfacherung der Schreibweise. Im Gegensatz zur Instanzvariable _property wird mit der Nachricht setProperty an meinObjekt dessen Setter-Methode für _property aufgerufen. Diese wird implizit erzeugt, du kannst sie aber auch explizit selbst schreiben wenn du zum Beispiel vor hast vorher noch bestimmte Bedingungen zu prüfen. Dort solltest du nur nicht den Fehler machen und self.property aufrufen um den Wert zu setzen, da du in diesem Fall dann unabsichtlich eine Rekursion ohne Abbruchbedingung hervorrufen würdest. Dort solltest du also stets die Instanzvariable nutzen.

Ansonsten sind Properties dazu da den Zugriff von außen auf Instanzvariablen unkompliziert zu regeln. Ob und inwiefern dies sinnvoll ist, ist eine andere Frage und dies wurde auch schon in anderen Threads diskutiert. Eine Instanzvariable ohne Property legst du einfach wie folgt an:

C-/C++-Quelltext

1
2
3
4
5
6
7
@interface MyClass : NSObject
{
    @private
    int _ivar;
}

@end


Bei deiner Frage inwiefern das sinnvoll ist müsstest du dich mit dem Prinzip der Kapselung in der OOP näher beschäftigen.

Initialisierer sind dazu da die Instanz einer Klasse mit sinnvollen Werten zu belegen nachdem sie erzeugt wurde, damit du anschließend damit arbeiten kannst. Dort kannst du Instanzvariablen im Prinzip auch über dessen Setter-Methode setzen sofern sie eine besitzen (also "self.property = value;"). Normalerweise ist das nicht nötig. Lediglich für die Ausnahme, dass die Settermethode etwas mehr macht als die Instanzvariable zu setzen (und vorher auf Bedingungen zu prüfen) kann dies von Bedeutung sein. In der Regel reicht ein "_property = value;" aus.

Ich hoffe ich konnte ein wenig helfen. Wenn du noch weitere Fragen hast dann schreib mir ruhig eine PM. Ich stelle mich gern zur Verfügung und beantworte sie dir dann ;).

Karim

Frischling

  • »Karim« ist der Autor dieses Themas

Beiträge: 7

Wohnort: Düsseldorf

  • Private Nachricht senden

3

26.09.2014, 14:07

Hallo spintop,

vielen lieben Dank für die schöne Erklärung! Das leuchtet mir jetzt schon alles ein wenig mehr ein :)

Bei weiteren Fragen würde ich dann gerne per PM auf dich zurückkommen :D Schon mal im Voraus vielen Dank für die angebotene Hilfe!

Lieben Gruß!

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

4

26.09.2014, 14:14

Ich würde generell empfehlen die Property zu verwenden statt der privaten dahinter liegenden Variable. Properties führen gern mal ein paar Checks durch (oder relevante anderweitige Änderung des Klassen-Zustands). Setzt man nur die private Variable, geschieht das natürlich nicht. Auch wenn es in 95% der Fälle eh nur eine reine Zuweisung und somit identisch ist, sind die anderen 5% die Stellen, die einem den Tag verderben. Daher sollte man sich gleich angewöhnen immer die Property zu verwenden. Ausnahmen nur explizit dann machen, wenn es durch die Verwendung der Property zu unerwünschten Effekten kommen könnte.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

Werbeanzeige