C# 在代码(MonoMac)中创建菜单项时崩溃

C# 在代码(MonoMac)中创建菜单项时崩溃,c#,mono,monomac,xamarin.mac,C#,Mono,Monomac,Xamarin.mac,我试图在运行时将一些菜单项动态添加到子菜单中。我可以很好地添加NSMenuItem,它就会显示出来。但是,如果我试图添加一个事件处理程序,或者直接作为构造函数的参数,或者通过将其分配给激活的事件,我会遇到崩溃。菜单和子菜单是在Xcode中创建的。我只是在运行时在一个特定的子菜单中添加/删除项 绘制子菜单时会发生崩溃。我右键单击,将鼠标移到关联菜单上,直到找到动态子菜单所在的项目,然后崩溃 坠机报告很长,但我认为以下是最相关的部分: Thread 1 (process 6706): #0 0x9

我试图在运行时将一些菜单项动态添加到子菜单中。我可以很好地添加NSMenuItem,它就会显示出来。但是,如果我试图添加一个事件处理程序,或者直接作为构造函数的参数,或者通过将其分配给激活的事件,我会遇到崩溃。菜单和子菜单是在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 ()
线程1(进程6706):
#0 0x94f73095英寸uu wait4()
#waitpid$UNIX2003中的1 0x9928699a()
#在最小异常情况下,2 0x004a7d22位于mono_handle_native_sigsegv(信号=11,ctx=0xf6fe0)中。c:2344
#3 0x004f7645位于exceptions-x86处的单声道拱形手柄altstack异常(sigctx=0xf6fe0,故障地址=0xc8080824,堆栈ovf=0)中。c:1135
#在mini.c:6556处的mono_sigsegv_信号处理程序(_dummy=11,info=0xf6fa0,context=0xf6fe0)中4 0x00404061
#5  
#objc_msgSend()中的6 0x98a83a8b
#7 0xbfffd920英寸??()
#8 0x9730c963 in-[NSCarbonMenuImpl\u carbonUpdateStatusEvent:handlerCallRef:()
#NSSLMMenuEventHandler()中的9 0x973086ee
#10 0x908f79bb在调用EventHandlerupp()中
#DispatchEventToHandlers()中的11 0x9077f394
#SendEventToEventTargetInternal()中的12 0x9077e780
#SendEventToEventTarget()中的13 0x90792655
#SendHICommandEvent()中的14 0x908f786a
#更新ICommandStatuswithCachedEvent()中的15 0x907535f0
#HIApplication::EventHandler()中的16 0x9077abe2
#17 0x908f79bb在调用EventHandlerupp()
#DispatchEventToHandlers()中的18 0x9077f394
#SendEventToEventTargetInternal()中的19 0x9077e780
#SendEventToEventTarget()中的20 0x90792655
#SendMenuOpening()中的21 0x90943054
#图纸菜单中的22 0x90752DF()
#打开子菜单()中的23 0x90945779
#TrackMenuCommon()中的24 0x90752427
#PopUpMenuSelectCore()中的25 0x9094490d
#26 0x909441e2在_HandlePopUpMenuSelection7()中
#27 0x97398295英寸碳菜单3()
#28 0x973971b1 in-[NSCarbonMenuImpl\u popUpContextMenu:withEvent:forView:withFont:()
#29 0x97515063 in-[NSMenu\u popUpContextMenu:With Event:forView:With Font:]()
#30 0x97514f56 in-[NSMenu\u popUpContextMenu:withEvent:forView:()
#31 0x97515390英寸-[NSMenu]弹出菜单,事件:forView:()
#32 0x9771af45英寸-[NSView RIGHT MOUSEDOWN:]()
#33 0x973ed635 in-[NSControl_rightMouseUpOrDown:()
#34 0x973ed69f输入-[NSControl rightMouseDown:]()
#35 0x971c8af1 in-[NSWindow sendEvent:]()
#36 0x971c390f in-[n应用程序发送事件:()
#37 0x970dd62c输入-[n应用程序运行]()
#NapplicationMain()中的38 0x970805f6
#39 0x06de146b英寸??()
#40 0x06de1290英寸??()
#41 0x000befe4英寸??()
#42 0x000bf12f英寸??()
#在mini.c:6438处,在mono_jit_运行时_调用(方法=0x9e8c1c,对象=0x0,参数=0xbffff468,exc=0x0)中有43 0x0040dc05
#44对象上的单运行时调用中的0x005c49ae(方法=0x9e8c1c,obj=0x0,参数=0xbffff468,exc=0x0)。c:2827
#对象上的mono_runtime_exec_main(方法=0x9e8c1c,参数=0xe7f30,exc=0x0)中的45 0x005c8dc4。c:4054
#对象上的mono运行时运行主(方法=0x9e8c1c,argc=0,argv=0x168d18,exc=0x0)中的46 0x005c9135。c:3678
#驱动程序处的mono_jit_exec(域=0x94e00,程序集=0x1833b0,argc=2,argv=0x168d18)中的47 0x00478685。c:955
#驱动程序处的单声道主路(argc=4,argv=0x168d10)中有48 0x0047abbf。c:1014
#主管道中的49 0x0000308f()

我正在运行Xamarin Studio 4.0.12、Mono 3.2.0、Xcode 4.6.3、Xamarin.Mac 1.4.8、OS X 10.8.4,我希望我们的经验能给我们带来一些启示。虽然没有任何代码,这是相当困难的

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

特别是使用Cocoa控制器样式的窗口,由于Cocoa似乎更乐于切换窗口/控制器并再次补水,因此预期在内存中始终引用的项被清除的风险要大得多

Tl;DR

  • 保留对菜单项的模块化引用—将它们存储在控制器的字段中。否则,它们可能会被收集
  • 在执行重新绘制之前,确保没有循环引用(Cocoa习惯于在属于对象的委托中定义行为,这比Windows容易得多)
  • 删除菜单项必须从头到尾(请记住,删除菜单项时,计数将减少)
  • 我们通常发现这种神秘的崩溃是由于控件和/或委托引用了引用委托的对象而消失

    我相信有了更多的代码,我可以帮助更多

    干杯
    伊恩

    我想我已经找到了问题所在。当我删除所有涉及
    Properties.Settings
    内容的代码时,崩溃似乎完全消失了。此类继承自
    System.Configuration.ApplicationSettingsBase
    。你可以在这里看到整个班级:

    这可能是我的错,因为我采用了这种简单的持久存储方法,并且使用它运行的距离超出了预期。因此,我的解决方案是转而使用SQLite,它可能在更多方面为我服务,而不仅仅是防止这些崩溃

    在任何情况下,这些碰撞似乎都是随机的。这可能是因为对这个类的访问主要是通过不同的线程完成的


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

    能否显示一些代码?实际代码如下:。但是,当我试图在一个空白项目中重现崩溃时,它似乎起了作用。这有一点,问题在哪里-哪一行?关闭解决方案或在新项目中重建解决方案往往会修复不属于您的错误。清洁代码顺便说一句!线