Плохой доступ в некоторых функциях Obj- C - PullRequest
0 голосов
/ 25 марта 2020

Так что я работаю над своего рода GLFW-lite framework и выполняю часть какао. Я пытаюсь заставить вход работать, но он не работает. По сути, мой интерфейс просмотра имеет указатель на структуру с массивом. Я точно знаю, что массив инициализируется, потому что в его функции инициализации я печатаю некоторые значения из него. (Также я инициализировал массив) Но в функции 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];
}

Если я пытаюсь получить доступ к ключам окна в функции инициализации интерфейс это работает. Так почему же это дает мне ошибку?

1 Ответ

1 голос
/ 25 марта 2020

Вот что происходит:

In main():

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

View A выделяется и вызывается init:.

In init:

win = window;

View A win равно window.

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

View B выделено и вызывается initWithFrame:.

return self;

View B возвращается. View B не имеет win.

Решение: не выделяйте еще View в init:.

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