objective-c - seleccionar - illustrator duplicar en circulo
Cómo copiar un objeto en el objetivo c (5)
Como siempre con los tipos de referencia, hay dos conceptos de "copiar". Estoy seguro de que los conoces, pero para completar.
- 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.
- 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 <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;
}
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!
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 <NSCopying>
{
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 <Foundation/Foundation.h>
@interface YourObject : NSObject <NSCopying>
@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:
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.
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];