Cocoa崩溃中的碳:释放NSAutoreleasePool后的EXC_BAD_ACCESS

时间:2009-11-06 19:47:12

标签: objective-c cocoa photoshop cocoa-bindings macos-carbon

我正在使用Bindings为Photoshop CS3插件开发Cocoa用户界面。 (Cocoa中的Carbon,因为PS是Carbon应用程序)当我关闭模态EXC_BAD_ACCESSNSWindow版本时,我收到NSAutoreleasePool错误。

我认为它与我的nib文件中的绑定和控件视图有关,因为当我从笔尖中删除复选框和单选按钮的绑定时,窗口可以无限次关闭并且不会崩溃。

我花了几个小时现在用仪器试图弄清楚哪个物体可能会提前释放(或双重释放)并找不到它。

现在我的想法是,在使用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个)

关闭所有绑定可以消除任何崩溃。

有什么想法吗?

2 个答案:

答案 0 :(得分:3)

你是正确的,绑定似乎导致问题,因为堆栈爬行指示。但是,我认为这只是症状,而不是问题。

如你所知,Carbon应用程序中的Cocoa可能很棘手。

当你写的时,“ExportWindowController runModalWindowForExport是这样的:”我能理解这些要点:

  1. ExportWindowController是一个基于NSWindowController的类?
  2. 如果是这样,你何时解雇窗口?我看到[自我关闭]但是,我没有看到与NSWindowController相关联的任何“关闭”选择器。你应该打电话:

    [[controller window] performClose:[NSApplication sharedApplication]];
    
  3. ? 3.此外,NSApp是否已实例化?你看到你的窗户了吗?我不得不使用[NSApplication sharedApplication]来使它有时正常工作....

    如果有任何帮助,请告诉我。

    编辑:2009年11月6日:美国东部时间16:15 :如果您只有一个Cocoa绑定会怎样?您是否首先发布绑定绑定的数据?也许你不应该这样......

    编辑:2009年11月9日:美国东部时间16:27 :我最近在使用一个与Carbon应用程序配合使用的插件。这个插件使用Cocoa作为基础。一切都很顺利,直到我将NSTrackingAreas添加到我的NSControls中。然后,当插件的NSAutorelease池被耗尽时,我开始看到各种崩溃。我通过调用每个NSControl的removeTrackingArea函数解决了这个问题。

    也许您需要为基于NSWindowController的对象做类似的事情?在dealloc选择器中,尝试在绑定到的每个对象上调用代码removeObserver:forKeyPath?

答案 1 :(得分:1)

如果在耗尽NSAutoreleasePool时崩溃,那是因为某些东西被过度释放。你应该能够打开Zombie检测来弄清楚是什么;找到被过度释放的对象的类型。

完全猜测,您是否在-dealloc中实施了ExportWindowController方法?如果是,您是-release一个由NIB加载创建的对象,加载时-retain没有出现?