1

我试图在运行时动态地将一些菜单项添加到子菜单中。我可以很好地添加 NSMenuItem 并显示出来。但是,如果我尝试添加一个事件处理程序,或者直接作为构造函数的参数,或者通过将其分配给 Activated 事件,我会崩溃。菜单和子菜单是在 Xcode 中创建的。我只是在运行时在一个特定的子菜单中添加/删除项目。

绘制子菜单时发生崩溃。我右键单击,将鼠标移到上下文菜单上,直到找到动态子菜单所在的项目,然后崩溃!

崩溃报告很长,但这是我认为最相关的部分:

Thread 1 (process 6706):
#0  0x94f73095 in __wait4 ()
#1  0x9928699a in waitpid$UNIX2003 ()
#2  0x004a7d22 in mono_handle_native_sigsegv (signal=11, ctx=0xf6fe0) at mini-exceptions.c:2344
#3  0x004f7645 in mono_arch_handle_altstack_exception (sigctx=0xf6fe0, fault_addr=0xc8080824, stack_ovf=0) at exceptions-x86.c:1135
#4  0x00404061 in mono_sigsegv_signal_handler (_dummy=11, info=0xf6fa0, context=0xf6fe0) at mini.c:6556
#5  <signal handler called>
#6  0x98a83a8b in objc_msgSend ()
#7  0xbfffd920 in ?? ()
#8  0x9730c963 in -[NSCarbonMenuImpl _carbonUpdateStatusEvent:handlerCallRef:] ()
#9  0x973086ee in NSSLMMenuEventHandler ()
#10 0x908f79bb in _InvokeEventHandlerUPP ()
#11 0x9077f394 in DispatchEventToHandlers ()
#12 0x9077e780 in SendEventToEventTargetInternal ()
#13 0x90792655 in SendEventToEventTarget ()
#14 0x908f786a in SendHICommandEvent ()
#15 0x907535f0 in UpdateHICommandStatusWithCachedEvent ()
#16 0x9077abe2 in HIApplication::EventHandler ()
#17 0x908f79bb in _InvokeEventHandlerUPP ()
#18 0x9077f394 in DispatchEventToHandlers ()
#19 0x9077e780 in SendEventToEventTargetInternal ()
#20 0x90792655 in SendEventToEventTarget ()
#21 0x90943054 in SendMenuOpening ()
#22 0x90752dfd in DrawTheMenu ()
#23 0x90945779 in OpenSubmenu ()
#24 0x90752427 in TrackMenuCommon ()
#25 0x9094490d in PopUpMenuSelectCore ()
#26 0x909441e2 in _HandlePopUpMenuSelection7 ()
#27 0x97398295 in _NSSLMPopUpCarbonMenu3 ()
#28 0x973971b1 in -[NSCarbonMenuImpl _popUpContextMenu:withEvent:forView:withFont:] ()
#29 0x97515063 in -[NSMenu _popUpContextMenu:withEvent:forView:withFont:] ()
#30 0x97514f56 in -[NSMenu _popUpContextMenu:withEvent:forView:] ()
#31 0x97515390 in -[NSMenu _popUpMenuWithEvent:forView:] ()
#32 0x9771af45 in -[NSView rightMouseDown:] ()
#33 0x973ed635 in -[NSControl _rightMouseUpOrDown:] ()
#34 0x973ed69f in -[NSControl rightMouseDown:] ()
#35 0x971c8af1 in -[NSWindow sendEvent:] ()
#36 0x971c390f in -[NSApplication sendEvent:] ()
#37 0x970dd62c in -[NSApplication run] ()
#38 0x970805f6 in NSApplicationMain ()
#39 0x06de146b in ?? ()
#40 0x06de1290 in ?? ()
#41 0x000befe4 in ?? ()
#42 0x000bf12f in ?? ()
#43 0x0040dc05 in mono_jit_runtime_invoke (method=0x9e8c1c, obj=0x0, params=0xbffff468, exc=0x0) at mini.c:6438
#44 0x005c49ae in mono_runtime_invoke (method=0x9e8c1c, obj=0x0, params=0xbffff468, exc=0x0) at object.c:2827
#45 0x005c8dc4 in mono_runtime_exec_main (method=0x9e8c1c, args=0xe7f30, exc=0x0) at object.c:4054
#46 0x005c9135 in mono_runtime_run_main (method=0x9e8c1c, argc=0, argv=0x168d18, exc=0x0) at object.c:3678
#47 0x00478685 in mono_jit_exec (domain=0x94e00, assembly=0x1833b0, argc=2, argv=0x168d18) at driver.c:955
#48 0x0047abbf in mono_main (argc=4, argv=0x168d10) at driver.c:1014
#49 0x0000308f in main ()

我正在运行 Xamarin Studio 4.0.12、Mono 3.2.0、Xcode 4.6.3、Xamarin.Mac 1.4.8、OS X 10.8.4

4

2 回答 2

0

我想我真的找到了问题所在。当我删除所有接触这些Properties.Settings东西的代码时,崩溃似乎完全消失了。这个类继承自System.Configuration.ApplicationSettingsBase. 你可以在这里看到整个课程:https ://code.google.com/p/yet-another-music-application/source/browse/trunk/Player/Core/Properties/Settings.Designer.cs?r=1838

这可能是我的错,因为我采用了这种简单的持久存储方法,并且使用它运行得比预期的要远。所以我的解决方案是改用 SQLite,这可能会以更多方式为我服务,而不仅仅是防止这些崩溃。

无论如何,崩溃似乎有些随机。这可能是因为对此类的访问主要是从各种线程完成的。

无论如何,我很确定这种组合是致命的。删除其中一个(事件处理程序或ApplicationSettingsBase)将删除崩溃。

于 2013-09-18T18:34:50.640 回答
0

我希望我们的经验能给我们一些启示。虽然没有任何代码,但它相当困难。

Xamarin.Mac 在从 c# 类型中抽象出这些东西方面做得非常出色。然而,无法避免的一件事是每个操作系统(尤其是窗口系统)时间绘制事件和资源保留的方式非常不同。

特别是对于 Cocoa 控制器样式的窗口,预期总是在内存中引用的项目已经被清理的风险要大得多,因为 Cocoa 似乎更乐意切换窗口/控制器并再次重新补水。

Tl;DR

  1. 保留对 menuItems 的模块化引用 - 将它们存储在控制器上的字段中。否则它们可以被收集。
  2. 在执行重绘之前,确保您没有循环引用(Cocoa 习惯于在属于对象的委托中定义行为,这比 Windows 容易得多)
  3. 删除菜单项必须从末尾到开始(记住计数会随着我们删除而减少)

我们通常发现这种神秘的崩溃是由于消失的控件和/或代表引用具有对委托的引用的对象的委托。

我敢肯定,有了更多代码,我可以提供更多帮助!

干杯伊恩

于 2013-09-18T11:22:04.250 回答