【问题标题】:Bad access in certain Obj-C Functions某些 Obj-C 函数中的错误访问
【发布时间】:2020-03-25 04:55:14
【问题描述】:

所以我正在开发一种 GLFW-lite 框架,并且正在做可可部分。我试图让输入工作,但它不工作。基本上,我的视图界面有一个指向其中包含数组的结构的指针。我知道数组已初始化,因为在它的初始化函数中,我从中打印出一些值。 (另外,我初始化了数组)但是在 keyDown 函数中,由于某种原因,它给了我一个 exc_bad_access 。我尽我所能在尽可能少的代码行中复制错误,同时仍然保持相同的程序结构。 (另外,不要对复制的结构为难我,这个库的设计方式更简洁。)

#include <Cocoa/Cocoa.h>
#include <stdlib.h>

typedef struct _Window {
    //For storing key states
    int *keys;
} Window;

int numKeys = 5;

Window* createWindow() {
    Window* window = malloc(sizeof(Window));

    window->keys = malloc(sizeof(int) * numKeys);
    memset(window->keys, 0, numKeys);

    return window;
}

@interface View : NSView {
    Window* win;
}
- (id) init:(Window*)window;
@end

@implementation View
- (id) init:(Window*)window {
    win = window;
    self = [[View alloc] initWithFrame: NSMakeRect(0, 0, 800, 600)];
    return self;
}

- (BOOL)acceptsFirstResponder {
    return YES;
}

- (void) keyDown:(NSEvent *)event {
    win->keys[4] = 1;
}
@end

int main() {
    [NSApplication sharedApplication];
    NSWindow *window = [[NSWindow alloc] initWithContentRect: NSMakeRect(0, 0, 800, 600)
                                                   styleMask: NSWindowStyleMaskClosable
                                                            | NSWindowStyleMaskTitled
                                                            | NSWindowStyleMaskResizable
                                                            | NSWindowStyleMaskMiniaturizable
                                                     backing: NSBackingStoreBuffered
                                                       defer: NO];
    [window center];
    [window setTitle:@"Window Title"];
    [window makeKeyAndOrderFront:nil];
    [window orderFrontRegardless];

    Window* keyStates = createWindow();

    View* view = [[View alloc] init:keyStates];

    [window setContentView:view];
    [window makeFirstResponder:view];

    [NSApp run];
}

如果我尝试在界面的初始化函数中访问窗口键,它会起作用。那么为什么它会给我这个错误呢?

【问题讨论】:

    标签: arrays objective-c memory nsevent


    【解决方案1】:

    会发生什么:

    main():

    View* view = [[View alloc] init:keyStates];
    

    View A 被分配,init: 被调用。

    init:

    win = window;
    

    View A 的winwindow

    self = [[View alloc] initWithFrame: NSMakeRect(0, 0, 800, 600)];
    

    View B 被分配,initWithFrame: 被调用。

    return self;
    

    View B 返回。 View B 没有win

    解决方案:不要在init: 中分配另一个View

    - (instancetype)init:(Window *)window {
        if (self = [super initWithFrame:NSMakeRect(0, 0, 800, 600)] {
            win = window;
        }
        return self;
    }
    

    【讨论】:

    • 天哪,非常感谢。我花了大约 6 或 7 个小时试图让它发挥作用。如果你愿意,你可以在github.com/james51332/neptune 上查看我的框架(目前我在 mac 上工作,所以它现在只能在 cocoa 上运行,但我会添加 win32)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-09-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-20
    相关资源
    最近更新 更多