在代码中创建MenuItem时崩溃(MonoMac)

时间:2013-08-23 16:49:14

标签: c# mono monomac xamarin.mac

我试图在运行时动态地将一些菜单项添加到子菜单中。我可以添加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

2 个答案:

答案 0 :(得分:0)

我希望我们的经验可以解释一下。虽然没有任何代码,但是相当困难。

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

特别是对于Cocoa Controller的窗口样式,预计在内存中总是被引用的项目风险要大得多,因为Cocoa似乎更乐于切换Windows /控制器并再次补充水分

<强>铊; DR

  1. 保持对menuItems的模块化引用 - 将它们存储在控制器的字段中。否则可以收集它们。
  2. 在进行重新绘制之前,请确保您没有循环引用(Cocoa习惯于在属于对象的代理中定义行为,这比Windows更容易)
  3. 删除菜单项必须从结尾到开始(记住计数会随着我们删除而减少)
  4. 我们一般发现这种神秘的崩溃是由于消失的控件和/或代表引用了对代表的引用的对象。

    我确信有更多代码我可以提供更多帮助!

    干杯 伊恩

答案 1 :(得分: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)可以消除崩溃。