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

点击AppKit showDefinition生成的释义视图时macOS应用崩溃求助

问题

macOS应用调用AppKit的showDefinition(for:at)生成释义视图后,点击该视图会崩溃,崩溃日志错误信息:

Fault: deferNSXPCInvocationOntoMainThread_block_invoke caught NSInternalInconsistencyException '_CPSSetFrontProcessWithOptions failed due to CGError -606 4294966690 fffffda2 (appIsDaemon)'

已尝试的解决措施:

  • 用DispatchQueue.main.async包裹相关代码
  • 将DefinitionWindow设为全局变量手动控制生命周期
    但问题仍未解决。

开发环境:macOS 14.3.1、Xcode 15

可复现的完整代码(需在隐私设置中开启辅助功能权限):

import Cocoa
import SwiftUI
import AppKit

class AppDelegate: NSObject, NSApplicationDelegate {
    func applicationDidFinishLaunching(_ notification: Notification) {
        NSEvent.addGlobalMonitorForEvents(matching: .keyDown) { [weak self] event in
            guard let self = self else { return }
            if event.modifierFlags.contains(.command) && event.charactersIgnoringModifiers == "c" {
                self.ShowWordDefinition()
            }
        }
        NSApp.servicesProvider = self
        NSApp.registerServicesMenuSendTypes([.string], returnTypes: [])
    }
    func ShowWordDefinition(){
        DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
            let attributedString = NSAttributedString(string:NSPasteboard.general.string(forType: .string)!)
            let DefinitionWindow = NSWindow(contentRect: NSRect(origin: .zero, size: NSSize(width: 1, height: 1)), styleMask: [.borderless], backing: .buffered, defer: false)
            // on the top
            DefinitionWindow.level = .floating
            let pointInWindow = NSPoint(x:0,y:0); //default value
            DefinitionWindow.contentView?.showDefinition(for: attributedString, at: pointInWindow)
            DefinitionWindow.orderFront(nil)
        }
    }
}
let delegate = AppDelegate()
let app = NSApplication.shared
app.delegate = delegate
app.run()

完整崩溃日志:

FAULT: deferNSXPCInvocationOntoMainThread_block_invoke caught NSInternalInconsistencyException '_CPSSetFrontProcessWithOptions failed due to CGError -606 4294966690 fffffda2 (appIsDaemon)' with backtrace (
"0 CoreFoundation __exceptionPreprocess + 176",
"1 libobjc.A.dylib objc_exception_throw + 60",
"2 CoreFoundation +[NSException exceptionWithName:reason:userInfo:] + 0",
"3 ViewBridge assertCGError + 80",
"4 ViewBridge -[NSRemoteView serviceWindowWouldActivate] + 724",
"5 CoreFoundation invoking
+ 148",
"6 CoreFoundation -[NSInvocation invoke] + 428",
"7 ViewBridge __deferNSXPCInvocationOntoMainThread_block_invoke + 120",
"8 ViewBridge __wrapBlockWithVoucher_block_invoke + 56",
"9 ViewBridge deferredBlockOpportunity_block_invoke_2 + 360",
"10 CoreFoundation CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK + 28",
"11 CoreFoundation __CFRunLoopDoBlocks + 356",
"12 CoreFoundation __CFRunLoopRun + 2440",
"13 CoreFoundation CFRunLoopRunSpecific + 608",
"14 HIToolbox RunCurrentEventLoopInMode + 292",
"15 HIToolbox ReceiveNextEventCommon + 648",
"16 HIToolbox _BlockUntilNextEventMatchingListInModeWithFilter + 76",
"17 AppKit _DPSNextEvent + 660",
"18 AppKit -[NSApplication(NSEventRouting) _nextEventMatchingEventMask:untilDate:inMode:dequeue:] + 716",
"19 AppKit -[NSApplication run] + 476",
"20 try main + 160",
"21 dyld start + 2360"
)

解决思路

崩溃根源是系统将你的应用识别为守护进程(Daemon),导致无法激活前端进程(CGError -606对应kCGErrorNotActivated,提示appIsDaemon)。以下是具体修复方案:

  • 改用标准macOS App项目结构
    当前代码是直接运行NSApplication的命令行式逻辑,没有完整的App Bundle,系统会判定为非GUI应用。需创建标准的macOS App项目,将业务逻辑迁移到AppDelegate或SwiftUI生命周期框架中,确保应用有正常的GUI身份。

  • 修正窗口使用方式
    临时创建的极小无边界窗口无法被系统正确识别为GUI窗口载体,建议直接使用应用的主窗口调用showDefinition:

    func ShowWordDefinition(){
        DispatchQueue.main.async {
            guard let text = NSPasteboard.general.string(forType: .string),
                  let mainWindow = NSApp.mainWindow,
                  let contentView = mainWindow.contentView else {
                return
            }
            let attributedString = NSAttributedString(string: text)
            // 转换鼠标位置到主窗口坐标系
            let mouseLocation = NSEvent.mouseLocation
            let windowPoint = contentView.convert(mouseLocation, from: nil)
            contentView.showDefinition(for: attributedString, at: windowPoint)
        }
    }
    
  • 检查应用激活权限配置
    查看Info.plist,如果存在LSUIElement键且值为YES,会让应用后台运行无法激活前端,需移除该键或设为NO;同时确认辅助功能权限已正确生效。

  • 优化全局事件监听的上下文
    全局键盘监控的回调执行上下文可能存在异常,建议改用应用内快捷键监听(如NSMenuItem绑定快捷键),或确保调用showDefinition时,应用主窗口已创建并处于可激活状态。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 01:42:35