【问题标题】:Weird error when executing code in Xcode 8在 Xcode 8 中执行代码时出现奇怪的错误
【发布时间】:2016-09-27 20:48:15
【问题描述】:

当我在我的 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
    }
}

编辑(被要求添加这个):我在 Timer 函数中运行此代码:

_ = 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 Clock Pro[2441:115266] [常规] 2016-09-27 13:35:00.856803 时钟专业版[2441:115266] [通用] 2016-09-27 13:35:00.856885 Clock Pro[2441:115266] * 由于未捕获的异常“NSGenericException”而终止应用程序,原因:“-[NSAlert runModal] 只能从主线程调用。其他线程上的行为未定义。 * 首先抛出调用栈: ( 0 CoreFoundation 0x00007fffaaefd52b 异常预处理 + 171 1 libobjc.A.dylib 0x00007fffbf5d5cad objc_exception_throw + 48 2 核心基础 0x00007fffaaf7ba0d +[NSException raise:format:] + 205 3 AppKit 0x00007fffa9323b44 _NSRunModal + 103 4 AppKit 0x00007fffa8dd757d -[NSAlert runModal] + 270 5 时钟专业版 0x000000010005aab8 _TFC9Clock_Pro14ViewController13AlarmAlertBoxfT_T_ + 344 6 时钟专业版 0x000000010002d053 _TFFC9Clock_Pro14ViewController5TimerFT_T_U_FT_T_ + 6563 7 时钟专业版 0x000000010000f317 _TTRXFo___XFdCb_ + 39 8 libdispatch.dylib 0x00000001009fe74d _d libc++abi.dylib:以 NSException 类型的未捕获异常终止

我在我的项目中经常使用这段代码,并且我没有遇到其他代码行的问题。我已经尝试了几件事来解决这个问题或解决它,但我没有成功。任何帮助都会很棒。

【问题讨论】:

  • 正如异常所说,-[NSAlert runModal] 必须在主线程上调用。您从后台线程调用AlarmAlertBox() 的某个地方。
  • 屏幕截图表明您有一个方法Timer(),在其中,您正在后台线程中调用一个作业。请编辑您的帖子并包含该部分代码。
  • @OOPer 感谢您的 cmets。我已经编辑了我的帖子并包含了请求的代码。
  • 您的问题非常有限,可以通过用DispatchQueue.main.async {...} 封闭一些部分来解决,但您的代码可能需要许多其他修复。特别糟糕的是async 块内的while-loop,它运行空循环直到满足某些条件,并消耗 CPU 核心和电池......你的应用程序将被称为“电池消耗者”。
  • @OOPer 好吧,它实际上不是电池消耗者,我已经解决了这个问题。这个循环每秒运行一次。它曾经消耗我的电池,但自从我完成了一秒一圈之后就没有了。

标签: swift xcode macos


【解决方案1】:

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

类似这样的:

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

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

您的代码很难阅读。

【讨论】:

  • 哦,我明白了。我会试试的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-02
  • 1970-01-01
  • 2015-12-21
  • 2011-12-16
  • 2020-05-28
相关资源
最近更新 更多