Ich habe vor kurzem versucht, ein älteres Xcode-Projekt zu kompilieren (das früher nur gut kompiliert wurde), und jetzt sehe ich viele Fehler dieser Form:
error: writable atomic property 'someProperty' cannot pair a synthesized setter/getter with a user defined setter/getter
Das Codemuster, das diese Fehler verursacht, sieht immer so aus:
// Interface:
@property (retain) NSObject * someProperty;
// Implementation:
@synthesize someProperty; // to provide the getter
- (void)setSomeProperty:(NSObject *)newValue
{
//..
}
Ich kann sehen, warum der Fehler generiert wird. Ich sage dem Compiler, meine Property-Accessors (sowohl Getter als auch Setter) zu synthetisieren, und überschreibe den Setter dann unmittelbar danach manuell. Dieser Code hat immer ein bisschen gerochen.
Was ist also der richtige Weg, dies zu tun? Wenn ich @dynamic
anstelle von @synthesize
verwende, muss ich auch den Getter schreiben. Ist das der einzige Weg?
Ich hatte das gleiche Problem und nach einigen Recherchen hier meine Schlussfolgerung zu diesem Problem:
Der Compiler warnt Sie vor einem @property
, den Sie als atomar deklariert haben (d. H. Indem Sie das Schlüsselwort nonatomic
weglassen). Sie bieten jedoch eine unvollständige Implementierung der Synchronisierung des Zugriffs auf diese Eigenschaft.
Diese Warnung verschwinden lassen:
Wenn Sie einen @property
für atomar erklären, führen Sie einen der folgenden Schritte aus:
@dynamic
oder;@synthesize
und behalten Sie den synthetisierten Setter und Getter oder;Wenn Sie den @property
mit (nonatomic)
deklarieren, können Sie manuelle und synthetisierte Implementierungen von Getter und Setter mischen.
Update: Ein Hinweis zur automatischen Objektsynthese
Seit LLVM 4.0 bietet CLang die Autosynthese für deklarierte Eigenschaften, die nicht @dynamic
sind. Wenn Sie @synthesize
nicht angeben, stellt der Compiler standardmäßig Getter- und Setter-Methoden für Sie bereit. Die Regel für atomare Eigenschaften ist jedoch immer noch dieselbe: Entweder lassen Sie den Compiler beide den Getter und den Setter angeben, OR implementieren Sie beide selbst!
Sie müssen den Getter auch implementieren. Beispiel:
// Interface:
@property (retain) NSObject * someProperty;
// Implementation:
- (void)setSomeProperty:(NSObject *)newValue
{
@synchronized (self)
{
// ...
}
}
- (NSObject *)someProperty
{
NSObject *ret = nil;
@synchronized (self)
{
ret = [[someProperty retain] autorelease];
}
return ret;
}
Diese Frage wird unter den anderen Top-Treffern, die Sie bei der Suche nach "Objective C-benutzerdefinierten Eigenschaften" erhalten, nicht mit Informationen zu "setter =" oder "getter =" aktualisiert.
Um weitere Informationen zu dieser Frage zu liefern:
Sie können den @ property-Aufruf mit Ihrer eigenen Methode durch Schreiben bereitstellen
@property(setter = MySetterMethod:, getter = MyGetterMethod)
Beachten Sie den Doppelpunkt für die angegebene Setter-Methode.
Referenz Apple-Dokumentation
EDIT: Ich bin nicht ganz sicher, wie die neuen Änderungen an Objective-Cs Eigenschaften (sie sind jetzt viel intelligenter) die Antworten auf diese Frage ändern. Vielleicht sollte alles als veraltet markiert werden.
Für andere, die diesen Fehler nicht aus dem beschriebenen Grund erhalten, haben Sie wahrscheinlich das gleiche Problem wie ich:
Sie haben eine @ -Eigenschaft mit demselben Namen wie eine - () - Methode.
Etwas wie das:
@property UIView *mainView;
-(UIView *)mainView;