Take the 2-minute tour ×

I have 3 methods one which gets a color and saves it as a data object in user defaults, one which draws a rectangle and fills it with the color saved in user defaults and one method which initialises and instance of NSColor with the color saved in user defaults when the app launches.

Below are the 3 methods, however the problem is i get this error when i build and run the app, can anyone understand why i get this error and what's wrong with my code.

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
     [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;
share|improve this question
add comment

2 Answers

up vote 4 down vote accepted

The problem is in your initWithFrame: method. _color is set with either [NSColor blackColor] or [NSUnarchiver unarchiveObjectWithData:data]. Both of these methods return autoreleased objects. You need to retain them to make sure they still exist when drawRect: is called. The easiest way would be to call [_color retain] after the unarchive, so that the blackColor will still be autoreleased if it gets replaced.

Also, make sure you release the old _color in setColor:. Right now it leaks a NSColor object every time it is called.

share|improve this answer
+1 for spotting the leak. –  dreamlax Feb 17 '11 at 0:04
Thank you, it worked, will mark as answer in 3 minutes, apparently i have to wait. –  Sami Feb 17 '11 at 0:05
add comment

This is your problem, I think:

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

You don't own the object returned by unarchiveObjectWithData: but you assign it to an instance variable and treat it as if it is owned by you. You can explicitly take ownership of the object just as you do in your setter, by using the copy method:

_color = [color1 copy];
share|improve this answer
add comment

Your Answer


