2011-02-16 3 views
0

J'ai 3 méthodes qui obtient une couleur et l'enregistre comme un objet de données dans les valeurs par défaut, un qui dessine un rectangle et le remplit avec la couleur enregistrée dans les valeurs par défaut et une méthode qui initialise et instance de NSColor avec la couleur enregistrée dans les valeurs par défaut de l'utilisateur lors du lancement de l'application. Voici les 3 méthodes, mais le problème est que je reçois cette erreur lorsque je crée et exécute l'application, quelqu'un peut-il comprendre pourquoi je reçois cette erreur et ce qui ne va pas avec mon code.Cause NSColor et NSUserDefaults; Programme reçu le signal: "EXC_BAD_ACCESS"

Program received signal: “EXC_BAD_ACCESS”.

- (void)setColor:(NSColor *)color 
{ 
    _color = [color copy]; 

    NSData *data = [NSArchiver archivedDataWithRootObject:_color]; 
    [[NSUserDefaults standardUserDefaults] setObject:data forKey:@"MyColor"]; 

    [self setNeedsDisplay:YES]; 
} 


    - (void)drawRect:(NSRect)rect 
{ 

    NSRect rect1 = NSInsetRect([self bounds], 4.0, 4.0); 
    NSBezierPath * path; 
    [_color set]; 
    path = [NSBezierPath bezierPathWithRoundedRect:rect1 
                xRadius:6.0 
                yRadius:6.0]; 
    [path fill]; 
} 

- (id)initWithFrame:(NSRect)frame 
{ 
    self = [super initWithFrame:frame]; 
    if (self == nil) 
     return nil; 

    _color = [NSColor blackColor]; 
    NSData *data = [[NSUserDefaults standardUserDefaults] objectForKey:@"MyColor"]; 
    if (data != nil){ 
    NSColor *color1 = [NSUnarchiver unarchiveObjectWithData:data]; 
    _color = color1;} 

    return self; 
} 

Répondre

4

Le problème est dans votre méthode initWithFrame:. _color est défini avec [NSColor blackColor] ou [NSUnarchiver unarchiveObjectWithData:data]. Ces deux méthodes renvoient des objets auto-libérés. Vous devez les conserver pour vous assurer qu'ils existent toujours lorsque drawRect: est appelée. Le plus simple serait d'appeler le [_color retain] après le désarchivage, de sorte que la couleur noire sera toujours autoeleased si elle est remplacée.

De même, assurez-vous de libérer l'ancienne _color dans setColor:. À l'heure actuelle, il fuit un objet NSColor chaque fois qu'il est appelé.

+0

+1 pour repérer la fuite. – dreamlax

+0

Merci, cela a fonctionné, marquera comme réponse dans 3 minutes, apparemment je dois attendre. – Sami

1

C'est votre problème, je pense:

NSColor *color1 = [NSUnarchiver unarchiveObjectWithData:data]; 
_color = color1; 

Vous ne possédez pas l'objet retourné par unarchiveObjectWithData: mais vous attribuez à une variable d'instance et de la traiter comme si elle vous appartient. Vous pouvez explicitement prendre possession de l'objet comme vous le faites dans votre setter, en utilisant la méthode copy:

_color = [color1 copy]; 
Questions connexes