Ich habe eine schreibgeschützte Eigenschaft in meiner Schnittstelle als solche deklariert:
@property (readonly, nonatomic, copy) NSString* eventDomain;
Vielleicht verstehe ich Eigenschaften falsch, aber ich dachte, wenn Sie es als deklarieren readonly
, können Sie den generierten Setter in der Implementierungsdatei ( .m
) verwenden, aber externe Entitäten können den Wert nicht ändern. Diese SO-Frage besagt, dass genau das passieren sollte. Das ist das Verhalten, nach dem ich bin. Wenn eventDomain
ich jedoch versuche, die Standardsetz- oder Punktsyntax zum Festlegen innerhalb meiner init-Methode zu verwenden, wird ein unrecognized selector sent to instance.
Fehler angezeigt. Natürlich bin ich auf @synthesize
dem Grundstück. Der Versuch, es so zu benutzen:
// inside one of my init methods
[self setEventDomain:@"someString"]; // unrecognized selector sent to instance error
Verstehe ich also die readonly
Erklärung zu einer Immobilie falsch ? Oder ist noch etwas los?
.h
? Ansonsten sehe ich nicht, wie dies einen öffentlichen Setter entlarven würde. DankeEiko und andere gaben richtige Antworten.
Hier ist ein einfacher Weg: Greifen Sie direkt auf die private Mitgliedsvariable zu.
Beispiel
In der Header-H-Datei:
@property (strong, nonatomic, readonly) NSString* foo;
In der Implementierungsdatei .m:
Das ist es, das ist alles was du brauchst. Kein Muss, keine Aufregung.
Einzelheiten
Ab Xcode 4.4 und LLVM Compiler 4.0 ( Neue Funktionen in Xcode 4.4 ) müssen Sie sich nicht mit den in den anderen Antworten beschriebenen Aufgaben herumschlagen:
synthesize
SchlüsselwortNach dem Deklarieren einer Eigenschaft
foo
können Sie davon ausgehen, dass Xcode eine private Mitgliedsvariable mit dem Präfix Unterstrich hinzugefügt hat:_foo
.Wenn die Eigenschaft deklariert wurde
readwrite
, generiert Xcode eine Getter-Methode mit dem Namenfoo
und einen Setter mit dem NamensetFoo
. Diese Methoden werden implizit aufgerufen, wenn Sie die Punktnotation (my Object.myMethod) verwenden. Wenn die Eigenschaft deklariert wurdereadonly
, wird kein Setter generiert. Das bedeutet, dass die mit dem Unterstrich benannte Hintergrundvariable selbst nicht schreibgeschützt ist. Diesreadonly
bedeutet einfach, dass keine Setter-Methode synthetisiert wurde und daher die Verwendung der Punktnotation zum Setzen eines Werts mit einem Compilerfehler fehlschlägt. Die Punktnotation schlägt fehl, weil der Compiler Sie daran hindert, eine nicht vorhandene Methode (den Setter) aufzurufen.Der einfachste Weg, dies zu umgehen, besteht darin, direkt auf die Mitgliedsvariable zuzugreifen, die mit dem Unterstrich benannt ist. Sie können dies auch tun, ohne diese Variable mit dem Unterstrich zu deklarieren! Xcode fügt diese Deklaration als Teil des Build / Compile-Prozesses ein, sodass Ihr kompilierter Code tatsächlich die Variablendeklaration enthält. Diese Deklaration wird jedoch nie in Ihrer ursprünglichen Quellcodedatei angezeigt. Keine Magie, nur syntaktischer Zucker .
Mit
self->
ist eine Möglichkeit, auf eine Mitgliedsvariable des Objekts / der Instanz zuzugreifen. Möglicherweise können Sie dies weglassen und einfach den Variablennamen verwenden. Ich bevorzuge jedoch die Verwendung des Pfeils self +, da sich mein Code dadurch selbst dokumentiert. Wenn Sie das sehenself->_foo
, wissen Sie ohne Mehrdeutigkeit, dass dies_foo
eine Mitgliedsvariable in dieser Instanz ist.Durch die Art und Weise, die Diskussion über Vor- und Nachteile der Eigenschaftenaccessoren gegen direkten Ivar Zugang ist genau die Art von nachdenklicher Behandlung , die Sie in Dr. lesen werden Matt Neuberg ‚s Programming iOS Buch. Ich fand es sehr hilfreich zu lesen und erneut zu lesen.
quelle
readonly
so deklarieren , dass keine andere Klasse sie festlegen darf.Eine andere Möglichkeit, mit schreibgeschützten Eigenschaften zu arbeiten, besteht darin, @synthesize zu verwenden, um den Sicherungsspeicher anzugeben. Beispielsweise
Dann in der Implementierung
Ihre Methoden können dann festgelegt werden
m_whatever
, da es sich um eine Mitgliedsvariable handelt.Eine andere interessante Sache, die ich in den letzten Tagen erkannt habe, ist, dass Sie schreibgeschützte Eigenschaften erstellen können, die von Unterklassen wie diesen beschreibbar sind:
(in der Header-Datei)
Dann in der Implementierung
Die Deklaration wird in der Header-Datei verwendet, sodass Unterklassen den Wert der Eigenschaft unter Beibehaltung ihrer Lesbarkeit aktualisieren können.
Etwas bedauerlich in Bezug auf das Verstecken und die Kapselung von Daten.
quelle
Siehe Anpassen vorhandener Klassen in den iOS-Dokumenten.
Schreibgeschützte Eigenschaften haben nur eine Getter-Methode. Sie können den Hintergrund ivar weiterhin direkt in der Klasse der Eigenschaft oder mithilfe der Schlüsselwertcodierung festlegen.
quelle
Sie verstehen die andere Frage falsch. In dieser Frage gibt es eine Klassenerweiterung, die folgendermaßen deklariert ist:
Dies erzeugt den Setter, der nur in der Implementierung der Klasse sichtbar ist. Wie Eiko sagt, müssen Sie eine Klassenerweiterung deklarieren und die Eigenschaftsdeklaration überschreiben, um den Compiler anzuweisen, nur innerhalb der Klasse einen Setter zu generieren.
quelle
Die kürzeste Lösung ist:
MyClass.h
MyClass.h
quelle
Wenn eine Eigenschaft als schreibgeschützt definiert ist, bedeutet dies, dass es effektiv keinen Setter gibt, der entweder intern für die Klasse oder extern von anderen Klassen verwendet werden kann. (dh: Sie werden nur dann einen "Getter" haben, wenn das Sinn macht.)
Von den Klängen her möchten Sie eine normale Lese- / Schreibeigenschaft, die als privat markiert ist. Dies können Sie erreichen, indem Sie die Klassenvariable in Ihrer Schnittstellendatei als solche als privat festlegen:
quelle