Swift 在Xcode 8中执行代码时出现奇怪的错误

Swift 在Xcode 8中执行代码时出现奇怪的错误,swift,xcode,macos,Swift,Xcode,Macos,当我在macOS项目中运行某种类型的代码时,我遇到了一个错误,我不知道如何修复它。下面是我得到的错误: 这是给我错误的代码: func AlarmAlertBox() { let alert = NSAlert() alert.messageText = AlarmTitleVar alert.informativeText = DescriptionVar alert.addButton(withTitle: "OK") let result = al

当我在macOS项目中运行某种类型的代码时,我遇到了一个错误,我不知道如何修复它。下面是我得到的错误:

这是给我错误的代码:

func AlarmAlertBox() {
    let alert = NSAlert()
    alert.messageText = AlarmTitleVar
    alert.informativeText = DescriptionVar
    alert.addButton(withTitle: "OK")
    let result = alert.runModal()
    switch(result) {
    case NSAlertFirstButtonReturn:
        print("OK", terminator: "")
    default:
        break
    }
}
编辑(被要求添加此代码):我正在计时器函数中运行此代码:

_ = DispatchQueue.global().async {

        var ReminderNum = 1

        self.ReminderCheckON = true

        while self.ReminderCheckON == true {
            let int : Int = ReminderNum
            let ReminderStr = String(int)
            let ReminderStuff = UserDefaults().string(forKey: ReminderStr) ?? ""
            ReminderNum = ReminderNum + 1
            if ReminderStuff == "" {
                self.ReminderCheckON = false
                ReminderNum = 1
            }

            if ReminderStuff.range(of: self.ReminderCurrentTime.stringValue) != nil
            {
                print("Alarm Time!")
                if self.DeleteAlarm == "ON" {
                    UserDefaults().set("-", forKey: ReminderStr)
                    self.AlarmsEnd()
                    self.UpcomingAlarms.stringValue = ""
                    self.ReminderList.removeAllItems()
                    self.AlarmsCheck()
                }

                self.AlarmTitleVar = UserDefaults().string(forKey: "T" + ReminderStr) ?? ""

                self.DescriptionVar = UserDefaults().string(forKey: "D" + ReminderStr) ?? ""

                self.ReminderCheckON = false

                self.ReminderRingToneVar = UserDefaults().string(forKey: "R" + ReminderStr) ?? "Alarm"

                if self.ReminderRingToneVar == "Spring" {
                    let Spring = NSSound(named: "Spring")
                    Spring!.play()
                    self.AlarmAlertBox()
                    Spring!.stop()
                }

                if self.ReminderRingToneVar == "Alarm" {
                    let Alarm = NSSound(named: "RingDing")
                    Alarm!.play()
                    self.AlarmAlertBox()
                    Alarm!.stop()
                }

                if self.ReminderRingToneVar == "Strings" {
                    let Strings = NSSound(named: "Strings")
                    Strings!.play()
                    self.AlarmAlertBox()
                    Strings!.stop()
                }

                if self.ReminderRingToneVar == "Happy" {
                    let Happy = NSSound(named: "Happy")
                    Happy!.play()
                    self.AlarmAlertBox()
                    Happy!.stop()
                }

                if self.ReminderRingToneVar == "Bouncy" {
                    let Bouncy = NSSound(named: "Joshua's Creation")
                    Bouncy!.play()
                    self.AlarmAlertBox()
                    Bouncy!.stop()
                }

                if self.ReminderRingToneVar == "Star-Spangled Banner" {
                    let StarSpangledBanner = NSSound(named: "The_United_States_Army_Old_Guard_Fife_and_Drum_Corps_-_02_-_United_States_National_Anthem_The_Star_Spangled_Banner")
                    StarSpangledBanner!.play()
                    self.AlarmAlertBox()
                    StarSpangledBanner!.stop()
                }
            }
        }
    }
调试窗口为我提供了以下信息:

2016-09-27 13:35:00.856685 Clock Pro[2441:115266][General]引发了未捕获的异常

2016-09-27 13:35:00.856732时钟专业[2441:115266][General] 2016-09-27 13:35:00.856803时钟专业版[2441:115266][General] 2016-09-27 13:35:00.856885 Clock Pro[2441:115266]*由于未捕获的异常“NSGenericeException”而终止应用程序,原因:“-[NSAlert runModal]只能从主线程调用。其他线程上的行为未定义。' *第一次抛出调用堆栈: ( 0 CoreFoundation 0x00007fffaaefd52b异常预处理+171 1 libobjc.A.dylib 0x00007fffbf5d5cad objc_异常_抛出+48 2 CoreFoundation 0x00007fffaaf7ba0d+[N异常提升:格式:][205 3应用套件0x00007fffa9323b44 _NSRunModal+103 4应用套件0x00007fffa8dd757d-[NSAlert运行模式]+270 5时钟Pro 0x000000010005aab8\u TFC9时钟\u Pro14ViewController13 AlarmAlertBoxFT\u T\u344 6 Clock Pro 0x000000010002d053\U TFFC9Clock\U Pro14ViewController5TimerFT\U FT\U+6563 7时钟专业版0x000000010000f317 8 libdispatch.dylib 0x00000001009fe74d libc++abi.dylib:以NSException类型的未捕获异常终止


我在我的项目中经常使用这段代码,而我在其他代码行中没有遇到问题。我尝试过几种方法来解决这个问题或解决它,但都没有成功。任何帮助都会很好。

正如Hamish已经评论过的,你需要在主线程上运行所有与UI相关的任务。这不是非常困难,使用的后台线程应该知道:

大概是这样的:

    if self.ReminderRingToneVar == "Spring" {
        DispatchQueue.main.async {
            let spring = NSSound(named: "Spring")
            spring!.play()
            self.AlarmAlertBox()
            spring!.stop()
        }
    }

顺便说一句,如果你有机会在公共空间分享你的代码(我的意思是,包括在问答网站上写一个问题),你最好遵循Swift的标准编码规则:仅对类型使用大写CamelCase


您的代码很难阅读。

正如Hamish已经评论的那样,您需要在主线程上运行所有与UI相关的任务。这不是很难,使用后台线程的人应该知道:

大概是这样的:

    if self.ReminderRingToneVar == "Spring" {
        DispatchQueue.main.async {
            let spring = NSSound(named: "Spring")
            spring!.play()
            self.AlarmAlertBox()
            spring!.stop()
        }
    }

顺便说一句,如果你有机会在公共空间分享你的代码(我的意思是,包括在问答网站上写一个问题),你最好遵循Swift的标准编码规则:仅对类型使用大写CamelCase


您的代码很难阅读。

正如异常所说,
-[NSAlert runModal]
必须在主线程上调用。您正在后台线程中调用
AlarmAlertBox()
。屏幕截图表明您有一个方法
Timer()
,在它里面,您正在后台线程中调用作业。请编辑您的帖子并包含这部分代码。@OOPer谢谢您的评论。我已经编辑了我的帖子并包含了所需的代码。您的问题非常有限,可以通过使用
DispatchQueue.main.async{…}将某些部分封装起来加以修复
,但您的代码可能需要许多其他修复程序。尤其糟糕的是
异步
块中的
while
-循环,它运行空循环,直到满足某些条件,并消耗CPU内核和电池…您的应用程序将被称为“电池食客”@OOPer好吧,它实际上不是一个电池消耗器,我已经修复了它。这个循环每秒运行一次。它用来消耗我的电池,但不是因为我每秒循环一次。正如异常所说,
-[NSAlert runModal]
必须在主线程上调用。您正在调用
AlarmAlertBox()的某个地方
来自后台线程。屏幕截图表明您有一个方法
Timer()
,在它里面,您正在后台线程中调用作业。请编辑您的帖子并包含这部分代码。@OOPer谢谢您的评论。我已经编辑了我的帖子并包含了所需的代码。您的问题非常有限,可以通过使用
DispatchQueue.main.async{…}将某些部分封装起来加以修复
,但您的代码可能需要许多其他修复程序。尤其糟糕的是
异步
块中的
while
-循环,它运行空循环,直到满足某些条件,并消耗CPU内核和电池…您的应用程序将被称为“电池食客”@OOPer好吧,它实际上不是一个吃电池的人,我已经修好了。这个循环每秒钟运行一次。它过去吃我的电池,但自从我一秒钟循环一次之后就不吃了。哦,我明白了。我来试试。哦,我明白了。我来试试。