Cómo copiar un objeto en el objective c

Necesito copiar profundamente un objeto personalizado que tenga objetos propios. He estado leyendo y estoy un poco confundido sobre cómo heredar NSCopying y cómo usar NSCopyObject. podria alguien ayudarme? ¡Gracias por leer!

Como siempre con los tipos de referencia, hay dos conceptos de “copiar”. Estoy seguro de que los conoces, pero para completar.

  1. Una copia bit a bit. En esto, simplemente copiamos el bit de memoria por bit; esto es lo que hace NSCopyObject. Casi siempre, no es lo que quieres. Los objetos tienen un estado interno, otros objetos, etc., y a menudo hacen suposiciones de que son los únicos que tienen referencias a esos datos. Las copias en bits rompen esta suposición.
  2. Una copia profunda y lógica. En esto, hacemos una copia del objeto, pero sin hacerlo realmente poco a poco, queremos un objeto que se comporte igual para todos los efectos, pero no es (necesariamente) un clon idéntico a la memoria del original – el manual de Objective C llama tal objeto “funcionalmente independiente” de su original. Debido a que los mecanismos para hacer estas copias “inteligentes” varían de una clase a otra, pedimos a los objetos que las realicen. Este es el protocolo NSCopying.

Quieres esto último Si este es uno de sus propios objetos, simplemente debe adoptar el protocolo NSCopying e implementar – (id) copyWithZone: (zona NSZone *). Eres libre de hacer lo que quieras; aunque la idea es que hagas una copia real de ti mismo y la devuelvas. Llama a copyWithZone en todos sus campos, para hacer una copia profunda. Un simple ejemplo es

@interface YourClass : NSObject  { 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; } 

La documentación de Apple dice

Una versión de subclase del método copyWithZone: debe enviar el mensaje al súper primero, para incorporar su implementación, a menos que la subclase desciende directamente de NSObject.

para agregar a la respuesta existente

 @interface YourClass : NSObject  { SomeOtherObject *obj; } // In the implementation -(id)copyWithZone:(NSZone *)zone { YourClass *another = [super copyWithZone:zone]; another.obj = [obj copyWithZone: zone]; return another; } 

No conozco la diferencia entre ese código y el mío, pero tengo problemas con esa solución, así que leo un poco más y descubro que tenemos que establecer el objeto antes de devolverlo. me refiero a algo así como

 #import  @interface YourObject : NSObject  @property (strong, nonatomic) NSString *nombre;//nombre del medicamento @property (strong, nonatomic) NSString *linea;//linea a la que pertenece @property (strong, nonatomic) NSMutableString *tags;//palabras por las que se puede encontrar en el buscador @property (strong, nonatomic) NSString *htmlSource;//código html para mostrar su contenido @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.nombre]; [copy setLinea: self.linea]; [copy setTags: self.tags]; [copy setHtmlSource: self.htmlSource]; return copy; } 

Pongo esta respuesta porque tengo muchos problemas con este problema, ¡y no tengo ni idea de por qué! No conozco la diferencia, pero está funcionando y puede ser útil:

 another.obj = [obj copyWithZone: zone]; 

Creo que esta línea causa pérdida de memoria, porque accedes a obj través de la propiedad que (supongo) está declarada como retain . Por lo tanto, el conteo de retención se incrementará por propiedad y copyWithZone .

Yo creo que debería ser:

 another.obj = [[obj copyWithZone: zone] autorelease]; 

o:

 SomeOtherObject *temp = [obj copyWithZone: zone]; another.obj = temp; [temp release]; 

También está 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 presentar efectos secundarios ya que este llama getters que a su vez pueden contener lógica.