0

I have a problem with my class.

I've written a HistoryCard class that store my temporary situation of my array carte but when I restore all of that, they all have the same value and exactly contains the copy of the last situation of my array carte . Going to the debugging area, I found that all of my array's elements have the same address but I can't understand why.

In my gioco I've the array carte of Card that has the actual condition and I want to save the past condition of this array in history

#import "Gioco.h"
#import "HistoryCard.h"

@interface Gioco()

@property (nonatomic,readwrite) int punteggioPartita;
@property (nonatomic,strong) NSMutableArray* carte; // of Card
@property (nonatomic,strong) NSMutableArray* history; // of HistoryCard Class

@end

The array carte contains instances of my class 'Card' .

@interface Card : NSObject

@property (nonatomic) BOOL chosen;
@property (nonatomic) BOOL match;


@end

By UI, when I click on a UIButton , I modify this the property of relative index in array 'carte'. It's works infact my gioco ( game in english ), works perfectly . So I would create a History of my gioco and for this reason, I would "freeze" every changes of my card game and I've written this HistoryCard Class. How you can see, every instances of this class, has this two properties that conserve the state of my game.

#import "Card.h"
@interface HistoryCard : Card

@property (nonatomic,readonly,strong) NSMutableArray* situationAtThisTime; //of Array
@property (nonatomic,readonly) int score;

-(instancetype)initWithCurrentSituation:(NSArray*)currentCardSituation
                        andCurrentScore:(int) scoreSituation;
                        //designer initializzer


@end



#import "HistoryCard.h"
#import "PlayingCard.h"

@interface HistoryCard()

@property (nonatomic,strong,readwrite) NSMutableArray* situationAtThisTime; //of Array
@property (nonatomic,readwrite) int score;

@end

@implementation HistoryCard

-(instancetype)initWithCurrentSituation:(NSMutableArray*)currentCardSituation
                        andCurrentScore:(int) scoreSituation{
    self=[super init];

    if (self) {
        self.situationAtThisTime=[NSMutableArray arrayWithArray:currentCardSituation];
        self.score=scoreSituation;
    }

    return self;
}

@end

When a touch arrives, starts a method in my gioco that changes the value of properties and for this reason I create a instances of HistoryCard that would freeze the actual state of array 'carte' and add it in the array history of my card game

HistoryCard* currentHistory=[[HistoryCard alloc] initWithCurrentSituation:self.carte andCurrentScore:self.punteggioPartita];

[self.history addObject:currentHistory];

The problem is : if my history array contains 3 HistoryCard instances, every of that , has the score property set correctly ( the score of the game in the past ) but the situationAtThisTime array, that are equals for all every instances and exactly contains the copy of the last situation of my array carte . It's like every array that I would save, points to the actual condition of my array carte

I've looking for here and I hadn't found anything that could help me. Only a little help in this question but I've not global variables.

Thank you.

PS I found a personal solution but I don't know if there's a method that would make for me that.

            NSMutableArray* now=[[NSMutableArray alloc]init];
            for (Card*card in self.carte) {
                Card* toSend=[[Card alloc]init];
                toSend.chosen=card.chosen;
                toSend.match=card.match;
                toSend.valore=card.valore;
                [now addObject:toSend];
            }

HistoryCard* currentHistory=[[HistoryCard alloc]initWithCurrentSituation:now
    andCurrentScore: self.punteggioPartita];

            [self.history addObject:currentHistory];

In this case I'm coping all of properties in a new instances of card.

8
  • Could you post code where you update self.carte, e.g. when you change it and when do you create your HistoryCard class, if you never change the values in self.carte, then you will have the problem you're currently facing. Commented Jul 17, 2016 at 0:14
  • You have several different arrays here. Which one has all of the same elements? Commented Jul 17, 2016 at 3:19
  • @user2002649 all of situationAtThisTime array's of HistoryCard instances have the same value. In this array I would save the "carte" array situation at time T of the game. The array "carte" contains my Card of the game.So when a touches arrives, it change a value of card that is in "carte" array. Commented Jul 17, 2016 at 8:46
  • You say it is happening when you restore the values? Can you show the code you are using to restore them? Commented Jul 17, 2016 at 10:15
  • Sorry but I think I was not clear. So I'm going to edit the question above. Commented Jul 17, 2016 at 11:59

1 Answer 1

0

self.situationAtThisTime=[NSMutableArray arrayWithArray:currentCardSituation]; copies the array but doesn't copy the cards in the array. Element 0 in each array points to the same card object. If you change this card then every element 0 is changed. You have to make a deep copy of the array with copies of the cards.

self.situationAtThisTime = [[NSMutableArray alloc] initWithArray:currentCardSituation copyItems:YES];
Sign up to request clarification or add additional context in comments.

3 Comments

I tried it but my app crashes with [PlayingCard copyWithZone:]: unrecognized selector sent to instance 0x7fd098d0f1c0, where PlayingCard is a subclass of Card
Have I to implement the copyWithZone: method for my personal copy ?
Yes, the PlayingCard and Card classes must conform to the NSCopying protocol.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.