【问题标题】:Crash when creating MenuItem in code (MonoMac)在代码中创建 MenuItem 时崩溃 (MonoMac)
【发布时间】:2013-09-19 02:34:50
【问题描述】:

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

【问题讨论】:

  • 你能显示一些代码吗?
  • 实际代码在这里:code.google.com/p/yet-another-music-application/source/browse/…。但是当我尝试在一个空白项目中重现崩溃时,它似乎可以工作。
  • 有点,问题出在哪里——哪一行?
  • 关闭解决方案或在新项目中重新构建它往往会修复不属于您的错误。顺便说一句,清洁代码!
  • 第 232 行是我添加事件处理程序的地方。当我这样做时,会发生崩溃,如果我不是一切都很好(菜单项是灰色的)。我正在慢慢添加越来越多的代码,以查看除了事件处理程序之外,我的项目的哪些部分会触发此崩溃。

标签: c# mono monomac xamarin.mac


【解决方案1】:

我希望我们的经验可以提供一些启示。虽然没有任何代码是相当困难的。

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

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

Tl;DR

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

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

我相信有了更多代码,我可以提供更多帮助!

干杯 伊恩

【讨论】:

    【解决方案2】:

    我想我确实找到了问题所在。当我删除所有涉及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)会删除崩溃。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-10-06
      相关资源
      最近更新 更多