Cocoa 中的 Carbon 崩溃:NSAutoreleasePool 释放后 EXC_BAD_ACCESS
我正在使用 Bindings 为 Photoshop CS3 插件开发 Cocoa 用户界面。 (Cocoa 中的 Carbon,因为 PS 是一个 Carbon 应用)当我关闭模态 NSWindow
和 NSAutoreleasePool
版本时,我收到 EXC_BAD_ACCESS
错误。
我相信这与我的 nib 文件中的绑定和控制视图有关,因为当我从笔尖中删除复选框和单选按钮的绑定时,窗口可以无限次关闭而不会崩溃。
我现在花了几个小时使用 Instruments 试图找出哪个对象可能会提前释放(或双重释放),但找不到它。
现在我的想法是,在使用 Cocoa Bindings 时,我可能缺少在 NSAutoreleasePool
中运行模式窗口的一些东西。就像在关闭窗口之前我应该做一些事情来“完成”所有绑定以防止它们向已释放的对象发送消息。
这是我正在做的事情的基本代码示例:
NSAutoreleasePool *localPool = [[NSAutoreleasePool alloc] init];
NSApplicationLoad();
ExportWindowController *controller = [[ExportWindowController alloc] initWithWindowNibName:EXPORT_CONTROLLER_NIB_NAME];
[controller showWindow:nil];
[NSApp runModalForWindow:[controller window]];
[controller close];
[controller release];
[localPool release];
通过调用关闭模态窗口:
[NSApp stopModal];
这是堆栈跟踪:
#0 0x97793869 in _cache_getMethod
#1 0x9779c6da in lookUpMethod
#2 0x97793da7 in _class_lookupMethodAndLoadCache
#3 0x97793953 in objc_msgSend
#4 0x96501151 in -[NSBinder releaseConnectionWithSynchronizePeerBinders:]
#5 0x96a10390 in -[NSValueBinder releaseConnectionWithSynchronizePeerBinders:]
#6 0x963ac895 in -[NSObject(_NSBindingAdaptorAccess) _releaseBindingAdaptor]
#7 0x964062f5 in -[NSView _releaseBindingAdaptor]
#8 0x96405784 in -[NSView _finalizeWithReferenceCounting]
#9 0x96404e2f in -[NSView dealloc]
#10 0x964ef163 in -[NSControl dealloc]
#11 0x9099a9d8 in CFRelease
#12 0x909c75bd in _CFAutoreleasePoolPop
.... more
打开 NSZombieEnabled 没有显示任何双重释放的对象(尽管 Photoshop 本身有 1 个)
关闭所有绑定可以避免任何崩溃。
有什么想法吗?
I'm developing a Cocoa user interface for a Photoshop CS3 plugin using Bindings. (Carbon in Cocoa, since PS is a Carbon app) I'm getting a EXC_BAD_ACCESS
error when I close my modal NSWindow
and the NSAutoreleasePool
releases.
I believe it has something to do with bindings and the control views I have in my nib file, because when I remove the bindings from the check boxes and radio buttons from the nib, the window can close an unlimited number of times and not crash.
I've spent hours now with Instruments trying to figure out which object might be getting released early (or double released) and cannot find it.
Now my thoughts are that maybe there is something I'm missing about running a modal window within an NSAutoreleasePool
while using Cocoa Bindings. Like maybe there is something I'm supposed to do before closing the window to "finalize" all the bindings to prevent them from sending messages to released objects.
Here is a basic code example of what I'm doing:
NSAutoreleasePool *localPool = [[NSAutoreleasePool alloc] init];
NSApplicationLoad();
ExportWindowController *controller = [[ExportWindowController alloc] initWithWindowNibName:EXPORT_CONTROLLER_NIB_NAME];
[controller showWindow:nil];
[NSApp runModalForWindow:[controller window]];
[controller close];
[controller release];
[localPool release];
The modal window is closed by a call to:
[NSApp stopModal];
Here is a stack trace:
#0 0x97793869 in _cache_getMethod
#1 0x9779c6da in lookUpMethod
#2 0x97793da7 in _class_lookupMethodAndLoadCache
#3 0x97793953 in objc_msgSend
#4 0x96501151 in -[NSBinder releaseConnectionWithSynchronizePeerBinders:]
#5 0x96a10390 in -[NSValueBinder releaseConnectionWithSynchronizePeerBinders:]
#6 0x963ac895 in -[NSObject(_NSBindingAdaptorAccess) _releaseBindingAdaptor]
#7 0x964062f5 in -[NSView _releaseBindingAdaptor]
#8 0x96405784 in -[NSView _finalizeWithReferenceCounting]
#9 0x96404e2f in -[NSView dealloc]
#10 0x964ef163 in -[NSControl dealloc]
#11 0x9099a9d8 in CFRelease
#12 0x909c75bd in _CFAutoreleasePoolPop
.... more
Turning on NSZombieEnabled did not turn up any double-released objects (although there was 1 from Photoshop itself)
Turning off all bindings gets rid of any crash.
Any ideas?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您是正确的,正如堆栈爬行所表明的那样,绑定似乎导致了问题。然而,我认为这只是症状,而不是问题。
如您所知,Carbon 应用程序中的 Cocoa 可能很棘手。
当您写“ExportWindowController runModalWindowForExport 是这样的:”时,我是否理解以下几点:
如果是这样,您什么时候关闭该窗口?我看到 [self close] 但是,我没有看到任何与 NSWindowController 关联的“关闭”选择器。如果您致电:
?
3. 另外,NSApp 是否已实例化?你看到你的窗户了吗?有时我不得不使用 [NSApplication sharedApplication] 才能使其正常工作......
让我知道这些是否有帮助。
编辑:2009 年 11 月 6 日:16:15 EST:如果您只有一个 Cocoa 绑定,会发生什么情况?您是否首先释放绑定所绑定的数据?如果是这样的话,也许您不应该这样做...
编辑:2009 年 11 月 9 日:16:27 EST:我最近正在开发一个与 Carbon 应用程序配合使用的插件。该插件以Cocoa为基础。一切都进展顺利,直到我将 NSTrackingAreas 添加到我的 NSControls 中。然后,当插件的 NSAutorelease 池被耗尽时,我开始看到各种崩溃。我通过调用每个 NSControl 的removeTrackingArea 函数解决了这个问题。
也许您需要为基于 NSWindowController 的对象做类似的事情?在 dealloc 选择器中,尝试在您绑定的每个对象上调用removeObserver:forKeyPath 代码?
You are correct that the bindings seem to be causing the problem as the stack crawl indicates. However, I think that is just the symptom, not the problem.
As you are aware, Cocoa in a Carbon application can be tricky.
When you write, "the ExportWindowController runModalWindowForExport is this:" am I to understand these points:
If so, when do you dismiss the window? I see [self close] but, I don't see any "close" selector associated with NSWindowController. Should you be calling:
?
3. Also, is NSApp instantiated? Do you see your window? I've had to use [NSApplication sharedApplication] to get it working right sometimes....
Let me know if any of this helps.
EDIT: Nov 6, 2009: 16:15 EST: What happens if you have only one Cocoa binding? Are you releasing the data that the binding is bound to first? Perhaps you shouldn't be if so...
EDIT: Nov 9, 2009: 16:27 EST:I was recently working in a plug-in that works with a Carbon application. This plug-in is using Cocoa as its basis. Everything was going splendidly until I added NSTrackingAreas to my NSControls. Then I started seeing all sorts of crashes when the plug-in's NSAutorelease pool was being drained. I solved this problem by calling each NSControl's removeTrackingArea function.
Perhaps you need to do something similar for your NSWindowController based object? In the dealloc selector, try calling code to removeObserver:forKeyPath on each object that you have a binding to?
如果 NSAutoreleasePool 被耗尽时崩溃,那是因为某些东西被过度释放。您应该能够打开僵尸检测来找出什么;查找被过度释放的对象的类型。
完全猜测,您是否在
ExportWindowController
中实现了-dealloc
方法?如果是这样,您是否-release
是由 NIB 加载创建的对象,而加载时未发生-retain
操作?If it is crashing when the NSAutoreleasePool is being drained, it is because something is being over-released. You should be able to turn on Zombie detection to figure out what; to find the type of the object being over-released.
At a complete guess, do you implement a
-dealloc
method inExportWindowController
? If so, are you-release
ing an object that was created by the NIB load for which a-retain
did not occur upon load?