NSColor 和 NSUserDefaults 原因;程序收到信号:“EXC_BAD_ACCESS”;

发布于 2024-10-18 04:16:01 字数 1214 浏览 4 评论 0原文

我有 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

伏妖词 2024-10-25 04:16:01

问题出在您的 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 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.

剧终人散尽 2024-10-25 04:16:01

我认为这是您的问题:

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

您不拥有 unarchiveObjectWithData: 返回的对象,但您将其分配给实例变量并将其视为您拥有的对象。您可以使用 copy 方法显式获取对象的所有权,就像在 setter 中一样:

_color = [color1 copy];

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];
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文