某些 Obj-C 函数中的错误访问
Bad access in certain Obj-C Functions
所以我正在研究一种 GLFW-lite 框架,并且正在做 cocoa 部分。我试图让输入工作,但它不工作。基本上,我的视图界面有一个指向其中包含数组的结构的指针。我知道数组已初始化,因为在它的初始化函数中我从中打印出一些值。 (另外,我初始化了数组)但是在 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];
}
如果我尝试访问界面初始化函数中的 window 键,它会起作用。那么为什么它会给我错误?
事情是这样的:
在main()
中:
View* view = [[View alloc] init:keyStates];
View
A被分配,init:
被调用
在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
.
解决方案:不要在 init:
.
中分配另一个 View
- (instancetype)init:(Window *)window {
if (self = [super initWithFrame:NSMakeRect(0, 0, 800, 600)] {
win = window;
}
return self;
}
所以我正在研究一种 GLFW-lite 框架,并且正在做 cocoa 部分。我试图让输入工作,但它不工作。基本上,我的视图界面有一个指向其中包含数组的结构的指针。我知道数组已初始化,因为在它的初始化函数中我从中打印出一些值。 (另外,我初始化了数组)但是在 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];
}
如果我尝试访问界面初始化函数中的 window 键,它会起作用。那么为什么它会给我错误?
事情是这样的:
在main()
中:
View* view = [[View alloc] init:keyStates];
View
A被分配,init:
被调用
在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
.
解决方案:不要在 init:
.
View
- (instancetype)init:(Window *)window {
if (self = [super initWithFrame:NSMakeRect(0, 0, 800, 600)] {
win = window;
}
return self;
}