Seit ich mit iOS-Apps und Ziel C arbeite, bin ich wirklich verwirrt über die verschiedenen Orte, an denen man Variablen deklarieren und definieren könnte. Einerseits haben wir den traditionellen C-Ansatz, andererseits haben wir die neuen ObjectiveC-Richtlinien, die zusätzlich OO hinzufügen. Könnten Sie mir helfen, die besten Praktiken und Situationen zu verstehen, in denen ich diese Speicherorte für meine Variablen verwenden und möglicherweise mein derzeitiges Verständnis korrigieren möchte?
Hier ist eine Beispielklasse (.h und .m):
#import <Foundation/Foundation.h>
// 1) What do I declare here?
@interface SampleClass : NSObject
{
// 2) ivar declarations
// Pretty much never used?
}
// 3) class-specific method / property declarations
@end
und
#import "SampleClass.h"
// 4) what goes here?
@interface SampleClass()
// 5) private interface, can define private methods and properties here
@end
@implementation SampleClass
{
// 6) define ivars
}
// 7) define methods and synthesize properties from both public and private
// interfaces
@end
- Mein Verständnis von 1 und 4 ist, dass es sich um dateibasierte Deklarationen und Definitionen im C-Stil handelt, die keinerlei Verständnis für das Konzept der Klasse haben und daher genau so verwendet werden müssen, wie sie in C verwendet würden. Ich habe sie gesehen wird zuvor für die Implementierung statischer variablenbasierter Singletons verwendet. Gibt es andere bequeme Verwendungszwecke, die mir fehlen?
- Ich gehe davon aus, dass Ivars außerhalb der @synthesize-Direktive fast vollständig auslaufen und daher größtenteils ignoriert werden können. Ist das der Fall?
- Zu 5: Warum sollte ich jemals Methoden in privaten Schnittstellen deklarieren wollen? Meine privaten Klassenmethoden scheinen ohne Deklaration in der Schnittstelle einwandfrei zu kompilieren. Ist es hauptsächlich für die Lesbarkeit?
Vielen Dank, Leute!
quelle
Lesen Sie zuerst die Antwort von @ DrummerB. Es ist ein guter Überblick über das Warum und was Sie im Allgemeinen tun sollten. In diesem Sinne zu Ihren spezifischen Fragen:
Hier finden Sie keine tatsächlichen Variablendefinitionen (dies ist technisch zulässig, wenn Sie genau wissen, was Sie tun, dies jedoch niemals tun). Sie können verschiedene andere Arten von Dingen definieren:
Externe sehen aus wie Variablendeklarationen, aber sie sind nur ein Versprechen, sie tatsächlich woanders zu deklarieren. In ObjC sollten sie nur zum Deklarieren von Konstanten und im Allgemeinen nur von Zeichenfolgenkonstanten verwendet werden. Zum Beispiel:
Sie würden dann in Ihrer
.m
Datei die tatsächliche Konstante deklarieren:Wie von DrummerB festgestellt, ist dies ein Vermächtnis. Setzen Sie hier nichts ein.
Ja.
Externe Konstanten wie oben beschrieben. Hier können auch statische Dateivariablen abgelegt werden. Dies entspricht Klassenvariablen in anderen Sprachen.
Ja
Aber sehr selten. Fast immer sollten Sie clang (Xcode) erlauben, die Variablen für Sie zu erstellen. Die Ausnahmen betreffen normalerweise Nicht-ObjC-Ivars (wie Core Foundation-Objekte und insbesondere C ++ - Objekte, wenn dies eine ObjC ++ - Klasse ist) oder Ivars mit seltsamer Speichersemantik (wie Ivars, die aus irgendeinem Grund nicht mit einer Eigenschaft übereinstimmen).
Im Allgemeinen sollten Sie @synthesize nicht mehr verwenden. Clang (Xcode) erledigt das für Sie und Sie sollten es zulassen.
In den letzten Jahren sind die Dinge dramatisch einfacher geworden. Der Nebeneffekt ist, dass es jetzt drei verschiedene Epochen gibt (Fragile ABI, Non-Fragile ABI, Non-Fragile ABI + Auto-Syntheisze). Wenn Sie also den älteren Code sehen, kann dies etwas verwirrend sein. Verwirrung aufgrund der Einfachheit: D.
quelle
Ich bin auch ziemlich neu, also vermassle ich hoffentlich nichts.
1 & 4: Globale Variablen im C-Stil: Sie haben einen dateiweiten Bereich. Der Unterschied zwischen den beiden besteht darin, dass die erste Datei für jeden verfügbar ist, der den Header importiert, während die zweite nicht.
2: Instanzvariablen. Die meisten Instanzvariablen werden mithilfe von Eigenschaften über Zugriffsmethoden synthetisiert und abgerufen / festgelegt, da dies die Speicherverwaltung angenehm und einfach macht und Ihnen eine leicht verständliche Punktnotation bietet.
6: Implementierungs-Ivars sind etwas neu. Es ist ein guter Ort, um private Ivars zu platzieren, da Sie nur das offenlegen möchten, was im öffentlichen Header benötigt wird, aber Unterklassen sie nicht AFAIK erben.
3 & 7: Öffentliche Methoden- und Eigenschaftsdeklarationen, dann Implementierungen.
5: Private Schnittstelle. Ich benutze immer private Schnittstellen, wann immer ich kann, um die Dinge sauber zu halten und eine Art Black-Box-Effekt zu erzeugen. Wenn sie nichts davon wissen müssen, legen Sie es dort ab. Ich mache es auch aus Gründen der Lesbarkeit, weiß nicht, ob es andere Gründe gibt.
quelle
Dies ist ein Beispiel für alle Arten von Variablen, die in Objective-C deklariert wurden. Der Variablenname gibt den Zugriff an.
Datei: Animal.h
Datei: Animal.m
Beachten Sie, dass die iNotVisible-Variablen von keiner anderen Klasse aus sichtbar sind. Dies ist ein Sichtbarkeitsproblem, daher wird es deklariert
@property
oder@public
nicht geändert.In einem Konstruktor empfiehlt es sich, auf Variablen zuzugreifen, die mit
@property
Unterstrichen deklariert wurdenself
, um Nebenwirkungen zu vermeiden.Versuchen wir, auf die Variablen zuzugreifen.
Datei: Cow.h
Datei: Cow.m
Wir können weiterhin über die Laufzeit auf die nicht sichtbaren Variablen zugreifen.
Datei: Cow.m (Teil 2)
Versuchen wir, auf die nicht sichtbaren Variablen zuzugreifen.
Datei: main.m
Dies wird gedruckt
Beachten Sie, dass ich auf den Hintergrund ivar zugreifen konnte, der
_iNotVisible2
für die Unterklasse privat ist. In Objective-C können alle Variablen gelesen oder gesetzt werden, auch die markierten@private
, ohne Ausnahmen.Ich habe keine zugehörigen Objekte oder C-Variablen aufgenommen, da es sich um verschiedene Vögel handelt. Wie bei C-Variablen ist jede Variable, die außerhalb von definiert ist
@interface X{}
oder@implementation X{}
eine C-Variable mit Dateibereich und statischem Speicher ist.Ich habe weder über Speicherverwaltungsattribute noch über schreibgeschützte / readwrite-, Getter- / Setter-Attribute gesprochen.
quelle