Respuestas:
Como siempre ocurre con los tipos de referencia, hay dos nociones de "copia". Estoy seguro de que los conoce, pero para completarlos.
Quieres lo último. Si este es uno de sus propios objetos, simplemente debe adoptar el protocolo NSCopying e implementar - (id) copyWithZone: (NSZone *) zone. Eres libre de hacer lo que quieras; aunque la idea es que hagas una copia real de ti mismo y la devuelvas. Llame a copyWithZone en todos sus campos para hacer una copia en profundidad. Un ejemplo simple es
@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
, o me estoy perdiendo algo aquí?
copyWithZone:
cumple con este criterio, por lo tanto, debe devolver un objeto con un recuento de retención de +1.
alloc
lugar de allocWithZone:
desde que se pasó la zona?
allocWithZone
.
La documentación de Apple dice
Una versión de subclase del método copyWithZone: debe enviar el mensaje a super primero, para incorporar su implementación, a menos que la subclase descienda directamente de NSObject.
para agregar a la respuesta existente
@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:'
. Supongo que esto solo es necesario cuando heredamos de alguna otra clase personalizada que implementacopyWithZone
No sé la diferencia entre ese código y el mío, pero tengo problemas con esa solución, así que leí un poco más y descubrí que tenemos que configurar el objeto antes de devolverlo. Me refiero a algo como:
#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;
}
Agregué esta respuesta porque tengo muchos problemas con este problema y no tengo ni idea de por qué está sucediendo. No sé la diferencia, pero está funcionando para mí y tal vez también pueda ser útil para otros :)
another.obj = [obj copyWithZone: zone];
Creo que esta línea causa una pérdida de memoria, porque accede a la obj
propiedad a través de la cual (supongo) se declara como retain
. Entonces, el conteo de retención aumentará por propiedad y copyWithZone
.
Creo que debería ser:
another.obj = [[obj copyWithZone: zone] autorelease];
o:
SomeOtherObject *temp = [obj copyWithZone: zone];
another.obj = temp;
[temp release];
También existe el uso del operador -> para copiar. Por ejemplo:
-(id)copyWithZone:(NSZone*)zone
{
MYClass* copy = [MYClass new];
copy->_property1 = self->_property1;
...
copy->_propertyN = self->_propertyN;
return copy;
}
El razonamiento aquí es que el objeto copiado resultante debe reflejar el estado del objeto original. Los "." El operador podría introducir efectos secundarios, ya que este llama a los captadores que, a su vez, pueden contener lógica.