NSColor 和 NSUserDefaults 原因;程序收到信号:“EXC_BAD_ACCESS”;
我有 3 种方法,一种获取颜色并将其保存为用户默认值中的数据对象,一种方法绘制一个矩形并用用户默认值中保存的颜色填充它,另一种方法使用用户默认值中保存的颜色初始化 NSColor 实例应用程序启动时默认。
下面是 3 种方法,但问题是我在构建和运行应用程序时收到此错误,任何人都可以理解为什么我收到此错误以及我的代码有什么问题。
程序收到信号:“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;
}
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
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;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
问题出在您的
initWithFrame:
方法中。 _color 使用[NSColor blackColor]
或[NSUnarchiver unarchiveObjectWithData:data]
设置。这两个方法都返回自动释放的对象。您需要保留它们以确保在调用drawRect:
时它们仍然存在。最简单的方法是在取消存档后调用[_color keep]
,这样如果 blackColor 被替换,它仍然会自动释放。另外,请确保在
setColor:
中释放旧的_color。现在,每次调用它时都会泄漏一个 NSColor 对象。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 whendrawRect:
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.我认为这是您的问题:
您不拥有
unarchiveObjectWithData:
返回的对象,但您将其分配给实例变量并将其视为您拥有的对象。您可以使用copy
方法显式获取对象的所有权,就像在 setter 中一样:This is your problem, I think:
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 thecopy
method: