目前我正在学习使用 Cocoa 进行 Mac 开发的 Obj-C。我用检查器制作了一个简单的文件浏览器,以查看文件的图标和一些信息。到目前为止,一切都很好。现在我将其设为基于文档,这样我就可以打开多个窗口。
为了告诉检查器应该检查哪个文件,我使用 NSWindowDidBecomeMainNotification
。在窗口之间切换时效果很好,但当我关闭所有窗口然后打开一个新窗口时,它会给出 EXC_BAD_ACCESS
。
这是处理通知的方法:
- (void)windowChanged: (NSNotification *)notification
{
NSWindow *window = [notification object];
BrowserWindow *doc = [[window windowController] document];
if (currentDocument != doc) {
[currentDocument.arrayController removeObserver: self
forKeyPath: @"selectionIndex"];
[icon setImage:nil];
[size setStringValue:@"-"];
[owner setStringValue:@"-"];
[filename setStringValue:@"(none selected)"];
[doc.arrayController addObserver: self
forKeyPath: @"selectionIndex"
options: NSKeyValueObservingOptionNew
context: NULL];
currentDocument = doc;
}
}
在 currentDocument.arrayController
上调用 removeObserver:forkeyPath:
时会发生错误。这有点道理,它试图删除不再存在的东西的观察者,因为窗口已关闭。但如何解决呢?我实在想不出其他的了..
有人能给我指出正确的方向吗?
非常感谢您的帮助! :)
--
事情变得越来越奇怪了..刚刚检查了可以从我得到的书的网站上下载的示例,他们使用相同的方法,但它工作得很好。找不到任何差异,这让我发疯。
--
解决了!稍后会详细介绍。
最佳答案
丹尼尔可能是对的:您可能不保留 currentDocument。使 currentDocument 成为属性:
@property (retain) BrowserWindow *currentDocument;
并在实现部分综合它:
@synthesize currentDocument;
并将您的代码更改为:
- (void) windowChanged: (NSNotification *) notification
{
NSWindow *window = [notification object];
BrowserWindow *doc = [[window windowController] document];
if (self.currentDocument != doc)
{
[self.currentDocument.arrayController removeObserver: self
forKeyPath: @"selectionIndex"];
[icon setImage: nil];
[size setStringValue: @"-"];
[owner setStringValue: @"-"];
[filename setStringValue: @"(none selected)"];
[doc.arrayController addObserver: self
forKeyPath: @"selectionIndex"
options: NSKeyValueObservingOptionNew
context: NULL];
self.currentDocument = doc;
}
}
您可能希望对图标、大小、所有者和文件名执行相同的操作。
并注意消息的警告:您可能一开始就没有将自己注册为观察者。
关于objective-c - 获取 EXC_BAD_ACCESS,不知道如何修复它,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7302512/