单击 AppKit 的 showDefinition(for:at) 创建的定义视图时崩溃

问题描述 投票:0回答:1

当我单击 AppKit 的 showDefinition(for:at) 函数生成的视图时,我的 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

我已经包含了创建视图的函数片段:

func ShowDefinition(selectedText : String) {
        DispatchQueue.main.async {
            let DefinitionWindow = NSWindow(contentRect: NSRect(origin: self.mouseLocation, size: NSSize(width: 1, height: 1)), styleMask: [.borderless], backing: .buffered, defer: false)
            DefinitionWindow.level = .floating
            guard let mainScreenFrame = NSScreen.main?.frame else {
                return
            }
            DefinitionWindow.contentView?.showDefinition(for: attributedString, at: pointInWindow)
            DefinitionWindow.orderFront(nil)
            
        }
    }

潜在的问题和疑虑:

是否存在与 UI 转换或主线程相关的问题?

showDefinition(for:at) 流程在内部到底是如何工作的?

也许,点击时视图的显示级别提升导致了冲突?

如果有人可以提供解决此问题的任何见解或指导,我们将不胜感激。谢谢!

swift macos appkit
1个回答
0
投票

感谢您协助解决我的疑问并提供宝贵的见解。对于我最初提供的不完整的代码,我深表歉意。下面是一个完整且可重现的代码片段,可以在终端项目模板中直接执行。请注意,它需要在隐私设置中授予辅助权限。

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()
© www.soinside.com 2019 - 2024. All rights reserved.