Antworten:
Wie immer bei Referenztypen gibt es zwei Begriffe von "Kopie". Ich bin sicher, Sie kennen sie, aber der Vollständigkeit halber.
Du willst Letzteres. Wenn dies eines Ihrer eigenen Objekte ist, müssen Sie einfach das Protokoll NSCopying übernehmen und implementieren - (id) copyWithZone: (NSZone *) zone. Sie können tun, was Sie wollen. Die Idee ist jedoch, dass Sie eine echte Kopie von sich selbst erstellen und diese zurückgeben. Sie rufen copyWithZone für alle Ihre Felder auf, um eine tiefe Kopie zu erstellen. Ein einfaches Beispiel ist
@interface YourClass : NSObject <NSCopying>
{
SomeOtherObject *obj;
}
// In the implementation
-(id)copyWithZone:(NSZone *)zone
{
// We'll ignore the zone for now
YourClass *another = [[YourClass alloc] init];
another.obj = [obj copyWithZone: zone];
return another;
}
autorelease
es nicht, oder vermisse ich hier etwas?
copyWithZone:
erfüllt diese Kriterien, daher muss ein Objekt mit einer Anzahl von +1 zurückgegeben werden.
alloc
anstatt allocWithZone:
seit die Zone übergeben wurde?
allocWithZone
.
Apple-Dokumentation sagt
Eine Unterklassenversion der copyWithZone: -Methode sollte die Nachricht zuerst an super senden, um ihre Implementierung einzubeziehen, es sei denn, die Unterklasse stammt direkt von NSObject ab.
zur vorhandenen Antwort hinzufügen
@interface YourClass : NSObject <NSCopying>
{
SomeOtherObject *obj;
}
// In the implementation
-(id)copyWithZone:(NSZone *)zone
{
YourClass *another = [super copyWithZone:zone];
another.obj = [obj copyWithZone: zone];
return another;
}
No visible @interface for 'NSObject' declares the selector 'copyWithZone:'
. Ich denke, dies ist nur erforderlich, wenn wir von einer anderen benutzerdefinierten Klasse erben, die implementiertcopyWithZone
Ich kenne den Unterschied zwischen diesem und meinem Code nicht, aber ich habe Probleme mit dieser Lösung. Deshalb habe ich ein bisschen mehr gelesen und festgestellt, dass wir das Objekt festlegen müssen, bevor wir es zurückgeben. Ich meine so etwas wie:
#import <Foundation/Foundation.h>
@interface YourObject : NSObject <NSCopying>
@property (strong, nonatomic) NSString *name;
@property (strong, nonatomic) NSString *line;
@property (strong, nonatomic) NSMutableString *tags;
@property (strong, nonatomic) NSString *htmlSource;
@property (strong, nonatomic) NSMutableString *obj;
-(id) copyWithZone: (NSZone *) zone;
@end
@implementation YourObject
-(id) copyWithZone: (NSZone *) zone
{
YourObject *copy = [[YourObject allocWithZone: zone] init];
[copy setNombre: self.name];
[copy setLinea: self.line];
[copy setTags: self.tags];
[copy setHtmlSource: self.htmlSource];
return copy;
}
Ich habe diese Antwort hinzugefügt, weil ich viele Probleme mit diesem Problem habe und keine Ahnung habe, warum es passiert. Ich kenne den Unterschied nicht, aber es funktioniert für mich und vielleicht kann es auch für andere nützlich sein :)
another.obj = [obj copyWithZone: zone];
Ich denke, dass diese Zeile einen Speicherverlust verursacht, weil Sie auf die obj
Eigenschaft through zugreifen, die (ich nehme an) als deklariert ist retain
. Die Anzahl der Einbehaltungen wird also durch das Eigentum und erhöht copyWithZone
.
Ich glaube es sollte sein:
another.obj = [[obj copyWithZone: zone] autorelease];
oder:
SomeOtherObject *temp = [obj copyWithZone: zone];
another.obj = temp;
[temp release];
Es gibt auch die Verwendung des Operators -> zum Kopieren. Beispielsweise:
-(id)copyWithZone:(NSZone*)zone
{
MYClass* copy = [MYClass new];
copy->_property1 = self->_property1;
...
copy->_propertyN = self->_propertyN;
return copy;
}
Die Argumentation hier ist, dass das resultierende kopierte Objekt den Zustand des ursprünglichen Objekts widerspiegeln sollte. Das "." Der Bediener könnte Nebenwirkungen einführen, da dieser Getter aufruft, die wiederum Logik enthalten können.