我正在使用Bindings为Photoshop CS3插件开发Cocoa用户界面。 (Cocoa中的Carbon,因为PS是Carbon应用程序)当我关闭模态EXC_BAD_ACCESS
和NSWindow
版本时,我收到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个)
关闭所有绑定可以消除任何崩溃。
有什么想法吗?
答案 0 :(得分:3)
你是正确的,绑定似乎导致问题,因为堆栈爬行指示。但是,我认为这只是症状,而不是问题。
如你所知,Carbon应用程序中的Cocoa可能很棘手。
当你写的时,“ExportWindowController runModalWindowForExport是这样的:”我能理解这些要点:
如果是这样,你何时解雇窗口?我看到[自我关闭]但是,我没有看到与NSWindowController相关联的任何“关闭”选择器。你应该打电话:
[[controller window] performClose:[NSApplication sharedApplication]];
? 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
没有出现?