Copiare un oggetto con NSCopying

Objective-C

Una richiesta che ci fanno spesso è quella di riuscire a copiare o duplicare degli oggetti.
Capita spesso infatti di avere un oggetto e volerlo duplicare per poi lavorarci sopra così da avere la possibilità di “tornare indietro”.
Ma questa possibilità è utile anche per molti altri scopi.

Objective-C ci da la possibilità di copiare un oggetto, ma per farlo deve essere conforme al protocollo NSCopying.

Come implementarlo

Creiamo il nostro classico oggetto di prova, SampleObject sottoclasse di NSObject.
Seguiamo le istruzioni come nell’articolo “Come salvare un oggetto per poi rileggerlo in seguito“.
Avremo quindi tre proprietà: name, birthDate e age.

Adesso però rendiamolo conforme al protocollo NSCopying aggiungendolo all’interfaccia:

@interface SampleObject : NSObject <NSCopying>

@property (nonatomic, strong) NSString*	name;
@property (nonatomic, strong) NSDate* birthDate;
@property (nonatomic, readwrite) NSInteger age;

@end

Poi nel file di implementazione andiamo ad aggiungere il metodo richiesto dal protocollo -copyWithZone:

- (id)copyWithZone:(NSZone *)zone
{
	SampleObject* object = [[self class] allocWithZone:zone];
	
	object->_name = [self.name copy];
	object->_birthDate = [self.birthDate copy];
	object->_age = self.age;
	
	return object;
}

Ciò che stiamo facendo e creare un oggetto dello stesso tipo in una zona di memoria predefinita per far sì che il sistema gestisca le cose come deve (per farla semplice), poi, tramite l’operatore “->” andiamo a copiare le proprietà dell’oggetto, che saranno le medesime dell’oggetto stesso.
Da notare che anche gli oggetti al suo interno dovranno essere copiati, altrimenti farete puntare le proprietà ad oggetti condivisi.

A questo punto possiamo creare delle copie di SampleObject, vediamo come:

Instanziamo l’oggetto nel nostro view controller:

SampleObject* object = [SampleObject new];
object.name = @"Andrea";
object.birthDate = [NSDate date];
object.age = 28;

Il debugger ci dirà:

Object name Andrea, birthDate 2014-11-01 13:16:46 +0000, age 28

Adesso creiamo una copia:

SampleObject* copiedObject = [object copy];

Se chiediamo al debugger i dati di questo oggetto ci ritroveremo la risposta:

copiedObject name Andrea, birthDate 2014-11-01 13:16:46 +0000, age 28

Ricordatevi che copiare gli oggetti significa duplicare anche lo spazio di memoria occupato, quindi fatelo con prudenza.

Scritto il