2011-01-07 2 views
2

Ich habe ein Problem beim Verständnis der Eigenschaften. Welche Art von Eigenschaft sollte ich schreiben, wenn ich möchte, dass ein Attribut nicht durch seine Accessoren geändert wird (Rückgabe durch Kopie) und durch Referenz (beibehalten) gesetzt wird.Eigenschaften, die Kopien von Objekten im Getter zurückgeben und Objekte im Setter beibehalten

Beispiel:

MyType* theAttribute = MyObject.attribute; 
[theAttribute changeSomething]; // Does not have to change the MyObject attribute, working with a copy return 

MyType tmpObject = [[MyType alloc] init]; 
MyObject.attribute = tmpObject; // Want a retain here 
[tmpObject release]; 

Antwort

4

erklären die Eigenschaft als im Header behalten:

@property (nonatomic. retain) MyType *attribute; 

In der Implementierungsdatei synthetisieren die iVar:

@synthesize attribute; 

Aber Ihre eigene Getter vorzusehen, die die eine synthetisierte außer Kraft setzen:

- (MyType)attribute { 
    return [attribute copy]; 
} 

ich ich bin nicht das zurückgegebene Objekt wissen autoreleasing, aber da die Frage, spezifiziert nicht iOS, ich schreibe das aus der Perspektive einer Garbage Collection-Umgebung.

+1

Da "atomar" die Standardeinstellung ist, müssen Sie auch den 'Setter' schreiben. Sie können synthetisierte Getter nicht mit manuell geschriebenen Sätzen mischen oder umgekehrt. (GCC kann dies passieren lassen, aber es ist falsch. LLVM 2.0 warnt richtig/Fehler auf solche Spielereien.) – bbum

+1

Danke, Bill. Ich habe meine Antwort geändert – Abizern

2

In einem solchen Fall sollten Sie Getter und Setter selbst schreiben.

+0

Sie müssen den Setter nicht selbst schreiben, nur der Getter. – Abizern

+0

Ja, wirklich, das habe ich vermisst. Vielen Dank. –

+0

Sie müssen den Setter selbst schreiben, wenn Sie "atomic" verwenden möchten. – bbum

1

Sie würden wahrscheinlich Ihre eigene Accessor (n) schreiben, aber ganz genau, wie hängt davon ab, ob Sie die kopierte „get“ zurückkehren wollen Autoreleased werden soll oder nicht:

  1. Die idiomatische Weise bewerkstelligen „copy "Dies ist eine normale" behalten "-Eigenschaft für Accessoren, und unterstützt auch die -copy oder -mutableCopy Methode. Die letzten beiden sind der Standard für das semantische Kopieren eines Objekts, und das zurückgegebene Objekt sollte eine Eigentumsrechte behalten.

  2. Wenn Sie die Accessor haben wollen -foo eine Kopie von „foo“ zurückkehren, so dass der Anrufer nicht die interne Versions manipulieren kann, das ist in Ordnung, aber dann würden Sie es selbst schreiben wie folgt aussehen:

-

- (Foo *)foo 
{ 
    return [[foo copy] autorelease]; 
} 
+0

Uhhh ... Gibt [foo copy] kein beibehaltenes Objekt zurück? Autoreleasing eines beibehaltenen Objekts? – Oliver

+0

@Oliver: Ja, '[foo copy]' gibt ein beibehaltenes Objekt zurück, aber nach Konvention sollte der Getter '-foo 'nicht, daher die Autorelease. Der resultierende Effekt ist beides, was der Angerufene möchte (eine Kopie der ursprünglichen Daten, die zurückgegeben werden sollen) und was der Aufrufer erwartet (ein Objekt, das ohne einen expliziten Freigabeaufruf fallengelassen werden kann). –

-2

Ich würde vorschlagen, nicht durch Kopie zurück. Dies wird Sie in der Speicherverwaltung stören. Wird es automatisch veröffentlicht? Nicht behalten? Zu viele Fragen.

Stattdessen empfehle ich folgendes:

MyType* attr = [MyType typeWithMyType:MyObject.attribute]; 

oder so etwas.

+1

Es gibt keine Fragen, wenn Sie die einfachen Speicherverwaltungsregeln befolgen; Methoden geben automatisch freigegebene Objekte zurück, und Sie geben nur das frei, was Sie zuweisen, behalten, kopieren oder änderbar kopieren. Auf diese Weise muss der Benutzer der Klasse auch eine Kopie verwenden und das Objekt nicht ändern, während das Übergeben einer Kopie dies durch das Design erzwingt, wodurch sich Sorgen darüber ergeben, ob von Getter zurückgegebene Werte kopiert werden sollen oder nicht. – Abizern

+0

Aber das ist der Punkt. Eine Retain-Eigenschaft, die eine automatisch freigegebene Kopie zurückgibt, verstößt gegen alle diese Regeln und Namenskonventionen. –

+0

Warum? Der Getter wirkt sich nicht auf das als Eigenschaft gespeicherte Objekt aus und gibt nur eine Kopie zurück. Wie wirkt sich die Speicherverwaltung einer _copy_ auf die Speicherverwaltung des _original_ aus? – Abizern