我有3个方法,一个获取颜色并将其保存为用户默认值中的数据对象,一个绘制矩形并用用户默认值保存的颜色填充它,一个方法用颜色初始化NSColor和NSColor实例应用程序启动时保存在用户默认值中。
以下是3种方法,但问题是我在构建和运行应用程序时遇到此错误,任何人都可以理解为什么我会收到此错误以及我的代码出了什么问题。
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;
}
答案 0 :(得分:4)
问题出在您的initWithFrame:
方法中。 _color设置为[NSColor blackColor]
或[NSUnarchiver unarchiveObjectWithData:data]
。这两种方法都返回自动释放的对象。您需要保留它们以确保在调用drawRect:
时它们仍然存在。最简单的方法是在取消归档后调用[_color retain]
,以便blackColor在被替换时仍然会被自动释放。
另外,请确保在setColor:
中释放旧的_color。现在它每次调用时都会泄漏一个NSColor对象。
答案 1 :(得分:1)
这是你的问题,我想:
NSColor *color1 = [NSUnarchiver unarchiveObjectWithData:data];
_color = color1;
您不拥有unarchiveObjectWithData:
返回的对象,但是您将其分配给实例变量并将其视为拥有它。您可以使用copy
方法明确获取对象的所有权,就像在setter中一样:
_color = [color1 copy];