web-dev-qa-db-fra.com

Comment puis-je faire une copie complète en Objective-C?

Je suis en train d'apprendre à développer iOS et je suis confus avec copie profonde . Par exemple, j'ai trois cours ci-dessous. Maintenant, je veux copier en profondeur ClassA, quelqu'un peut-il m'apprendre à terminer la méthode de copie? 

UNE:

@interface ClassA : NSObject <NSCopying>

@property (nonatomic, assign) int aInt;
@property (nonatomic, retain) ClassB *bClass;

@end

B:

@interface ClassB : NSObject <NSCopying>

@property (nonatomic, assign) int bInt;
@property (nonatomic, retain) ClassC *cClass;

@end

C:

@interface ClassC : NSObject <NSCopying>

@property (nonatomic, assign) int cInt;
@property (nonatomic, copy) NSString *str;

@end
21
Fantasy

Vous devez ajouter la méthode copyWithZone: dans chaque classe que vous voulez être copiable.

NB: Je l'ai écrit à la main, faites attention aux fautes de frappe.

-(id) copyWithZone:(NSZone *) zone
{
    ClassA *object = [super copyWithZone:zone];
    object.aInt = self.aInt;
    object.bClass = [self.bClass copyWithZone:zone];
    return object;
}

-(id) copyWithZone:(NSZone *) zone
{
    ClassB *object = [super copyWithZone:zone];
    object.bInt = self.bInt;
    object.cClass = [self.cClass copyWithZone:zone];
    return object;
}

-(id) copyWithZone:(NSZone *) zone
{
    ClassC *object = [super copyWithZone:zone];
    object.cInt = self.cInt;
    object.str = [self.str copy];
    return object;
}
13
James Webster

Suite à l'explication sur http://www.techotopia.com/index.php/Copying_Objects_in_Objective-C

"Cela peut être réalisé en écrivant l'objet et ses éléments constitutifs dans une archive, puis en les lisant dans le nouvel objet."

@implementation ClassA

- (id)copyWithZone:(NSZone*)zone{
    NSData *buffer;
    buffer = [NSKeyedArchiver archivedDataWithRootObject:self];
    ClassA *copy = [NSKeyedUnarchiver unarchiveObjectWithData: buffer];
    return copy;
}
@end
19
cohen72

Objective-C sur iOS n’offre pas de construction directe de langage ou de bibliothèque pour basculer entre une copie superficielle et une copie profonde. Chaque classe définit ce que signifie “obtenir sa copie”:

@implementation ClassA

- (id) copyWithZone: (NSZone*) zone
{
    ClassA *copy = [super copyWithZone:zone];
    [copy setBClass:bClass]; // this would be a shallow copy
    [copy setBClass:[bClass copy]]; // this would be a deep copy
    return copy;
}

@end

Bien sûr, vous devrez prendre la même décision dans ClassB et ClassC. Si je ne me trompe pas, la sémantique habituelle d'une copie dans Objective-C consiste à renvoyer une copie superficielle. Voir aussi cette question sur la copie de tableaux pour plus d'informations sur le sujet.

11
zoul

J'avais des classes personnalisées avec de longues listes de propriétés, alors j'ai itéré dessus:

@interface MyClass : NSObject <NSCopying>

#import <objc/runtime.h>

-(id) copyWithZone: (NSZone *) zone {

    MyClass *myCopy = [[MyClass alloc] init];

    //deepCopy
    unsigned int numOfProperties;
    objc_property_t *properties = class_copyPropertyList([self class], &numOfProperties);

    for (int i = 0; i < numOfProperties; i++) {

       objc_property_t property = properties[i];
       NSString *propertyName = [[NSString alloc]initWithCString:property_getName(property) encoding:NSUTF8StringEncoding];
       [adressCopy setValue:[[self valueForKey:propertyName] copy] forKey:propertyName];
    }
    return myCopy;
}

Tous les customClassProperties devront également implémenter cela.

1
Yedy

Cela pourrait être utile. Le lien montre comment faire la copie complète en utilisant NSKeyedArchiver

http://iphonecodecenter.wordpress.com/2013/08/26/difference-between-shallow-copy-and-deep-copy/

0
Easwaramoorthy K