You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

迁移Xamarin.Mac至.NET macOS遇AppKit.NSWindow异常及窗口控制器问题求助

.NET macOS迁移:NSWindow/窗口控制器问题解析与修复

问题背景

  • 原Xamarin.Mac原生应用迁移至.NET macOS时,发现找不到AppKit.NSWindow,且.NET macOS项目模板默认仅提供视图及视图控制器支持,需明确窗口/窗口控制器的转换逻辑
  • 复制原有窗口和窗口控制器代码后,执行以下代码触发异常:
homeWindowController = new HomeWindowController ();
CommonClass.HomeController = homeWindowController;
homeWindowController.Window.MakeKeyAndOrderFront (this);

错误详情

Objective-C exception thrown.  Name: NSInternalInconsistencyException Reason: initWithWindowRef: is not currently supported for NSWindow subclasses!
Native stack trace:
	0   CoreFoundation                      0x000000018477c570 __exceptionPreprocess + 176
	1   libobjc.A.dylib                     0x000000018426deb4 objc_exception_throw + 60
	2   CoreFoundation                      0x000000018477c460 +[NSException exceptionWithName:reason:userInfo:] + 0
	3   AppKit                              0x0000000188991398 -[NSWindow(NSCarbonExtensions) initWithWindowRef:]

原因分析

  1. NSWindow并非移除:.NET macOS中AppKit.NSWindow依然存在,只是默认项目模板(尤其是基于AppKit的新模板)采用了以视图控制器为核心的启动逻辑,并非不支持窗口控制器
  2. 报错直接原因:原Xamarin.Mac的窗口控制器初始化逻辑依赖旧的绑定实现,触发了.NET macOS中已废弃的initWithWindowRef:方法,该方法不再支持NSWindow子类调用

转换与修复方法

1. 确保NSWindow的正确引用

确认项目已安装Microsoft.Mac.AppKit NuGet包,代码中添加命名空间引用:

using AppKit;

2. 窗口控制器的正确实现

根据窗口的创建方式(XIB/纯代码)选择对应方案:

基于XIB/Storyboard的窗口

窗口控制器需通过XIB文件加载,而非直接无参实例化子类:

// 方式1:直接使用NSWindowController加载XIB
homeWindowController = new NSWindowController("HomeWindow", NSBundle.MainBundle);

// 方式2:自定义控制器时,在构造函数中调用基类的XIB加载方法
public class HomeWindowController : NSWindowController
{
    public HomeWindowController() : base("HomeWindow", NSBundle.MainBundle)
    {
    }
}

注意:XIB文件的Build Action需设置为InterfaceDefinition,且窗口的File's Owner需绑定到对应的自定义窗口控制器类

纯代码创建窗口

直接实例化NSWindow并关联到窗口控制器,绕过旧的初始化路径:

// 创建NSWindow实例
var windowFrame = new CoreGraphics.CGRect(100, 100, 800, 600);
var window = new NSWindow(
    windowFrame,
    NSWindowStyle.Titled | NSWindowStyle.Closable | NSWindowStyle.Resizable,
    NSBackingStore.Buffered,
    false
);

// 关联到自定义窗口控制器
homeWindowController = new HomeWindowController(window);

3. 修复现有调用代码

替换原实例化逻辑后,重新调用窗口显示方法:

homeWindowController = new HomeWindowController(); // 若已在构造函数中处理XIB加载
CommonClass.HomeController = homeWindowController;
homeWindowController.Window.MakeKeyAndOrderFront(this);

4. 适配项目启动逻辑

若原应用为多窗口架构,需调整项目的启动入口,确保从窗口控制器启动:
在Program.cs中修改启动逻辑(示例):

using AppKit;

namespace YourAppName
{
    class Program
    {
        static void Main(string[] args)
        {
            NSApplication.Init();
            var windowController = new HomeWindowController();
            windowController.Window.MakeKeyAndOrderFront(null);
            NSApplication.Main(args);
        }
    }
}

内容的提问来源于stack exchange,提问作者Roshil K

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 14:21:16