以 NSException 计时器类型的未捕获异常终止 Swift 崩溃
Terminating With Uncaught Exception Of Type NSException Timer Swift Crash
我正在尝试在 swift 中使用计时器 class,但我的应用程序一直因信号 SIGBART 而崩溃,并且还因类型为 NSException 错误的未捕获异常而终止。请帮忙。谢谢
我已将其缩小为因为我的计时器,但我不知道如何解决它。
import UIKit
import AVFoundation
class playSound
{
var audioPlayer:AVAudioPlayer?
var bpm: Int
var switchOn: Bool
init(switchOn: Bool, bpm: Int)
{
self.bpm = bpm
self.switchOn = switchOn
}
func startSound()
{
self.switchOn = true
}
func changeBpm(bpm:Int)
{
self.bpm = bpm
}
func stopSound()
{
self.audioPlayer?.pause()
self.switchOn = false
}
@objc func repeatSound()
{
DispatchQueue.global(qos: .background).async
{
while (true)
{
let sleepAmount:Float = Float(abs((60/self.bpm)-1))
//print(self.bpm)
//print(sleepAmount)
if (self.switchOn == true)
{
print("hello")
let url = Bundle.main.url(forResource: "click", withExtension: "mp3")
guard url != nil else
{
return
}
do
{
self.audioPlayer = try AVAudioPlayer(contentsOf: url!)
self.audioPlayer?.play()
print(self.bpm)
}
catch
{
print("error")
}
}
}
}
}
}
class ViewController: UIViewController
{
var timer = Timer()
@IBOutlet weak var lbl: UILabel!
@IBOutlet weak var stepperView: UIStepper!
@IBOutlet weak var sliderView: UISlider!
var clickClass = playSound(switchOn: false, bpm: 120)
override func viewDidAppear(_ animated: Bool)
{
clickClass.repeatSound()
}
@IBAction func `switch`(_ sender: UISwitch)
{
do
{
if sender.isOn == true
{
// this is the code causing the error
timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(clickClass.repeatSound), userInfo: nil, repeats: true)
print("play")
}
else
{
timer.invalidate()
clickClass.stopSound()
print("pause")
}
}
}
}
我希望应用每秒播放一次声音。
错误是:
2019-06-13 22:49:38.226089-0700 Metronome[6695:2566182] -[Metronome.ViewController repeatSound]: unrecognized selector sent to instance 0x145e11dc0
2019-06-13 22:49:38.229502-0700 Metronome[6695:2566182] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[Metronome.ViewController repeatSound]: unrecognized selector sent to instance 0x145e11dc0'
*** First throw call stack:
(0x18144127c 0x18061b9f8 0x18135dab8 0x1adc27f60 0x181446ac4 0x18144875c 0x181ec88a4 0x1813d3650 0x1813d3380 0x1813d2bb4 0x1813cdb04 0x1813cd0b0 0x1835cd79c 0x1adbfc978 0x100ffccf0 0x180e928e0)
libc++abi.dylib: terminating with uncaught exception of type NSException
连同Thread 1: signal SIGABRT
您向计时器传递了错误的目标。你想传递 clickClass
,而不是 self
。并且选择器不应该引用变量,它应该引用 class.
timer = Timer.scheduledTimer(timeInterval: 1, target: clickClass, selector: #selector(playSound.repeatSound), userInfo: nil, repeats: true)
您还应注意正确命名。 Class、结构和枚举名称应以大写字母开头。变量、函数和案例名称应以小写字母开头。
您在代码中为计时器设置的目标不正确。将目标更改为 self.clickClass
,如下所示:
timer = Timer.scheduledTimer(timeInterval: 1, target: self.clickClass, selector: #selector(clickClass.repeatSound), userInfo: nil, repeats: true)
对于 self
目标,应用程序会尝试在同一个 viewcontroller 中找到 repeatSound
方法。另请遵循以下 link 以获取 swift 命名约定的最佳实践:
我正在尝试在 swift 中使用计时器 class,但我的应用程序一直因信号 SIGBART 而崩溃,并且还因类型为 NSException 错误的未捕获异常而终止。请帮忙。谢谢
我已将其缩小为因为我的计时器,但我不知道如何解决它。
import UIKit
import AVFoundation
class playSound
{
var audioPlayer:AVAudioPlayer?
var bpm: Int
var switchOn: Bool
init(switchOn: Bool, bpm: Int)
{
self.bpm = bpm
self.switchOn = switchOn
}
func startSound()
{
self.switchOn = true
}
func changeBpm(bpm:Int)
{
self.bpm = bpm
}
func stopSound()
{
self.audioPlayer?.pause()
self.switchOn = false
}
@objc func repeatSound()
{
DispatchQueue.global(qos: .background).async
{
while (true)
{
let sleepAmount:Float = Float(abs((60/self.bpm)-1))
//print(self.bpm)
//print(sleepAmount)
if (self.switchOn == true)
{
print("hello")
let url = Bundle.main.url(forResource: "click", withExtension: "mp3")
guard url != nil else
{
return
}
do
{
self.audioPlayer = try AVAudioPlayer(contentsOf: url!)
self.audioPlayer?.play()
print(self.bpm)
}
catch
{
print("error")
}
}
}
}
}
}
class ViewController: UIViewController
{
var timer = Timer()
@IBOutlet weak var lbl: UILabel!
@IBOutlet weak var stepperView: UIStepper!
@IBOutlet weak var sliderView: UISlider!
var clickClass = playSound(switchOn: false, bpm: 120)
override func viewDidAppear(_ animated: Bool)
{
clickClass.repeatSound()
}
@IBAction func `switch`(_ sender: UISwitch)
{
do
{
if sender.isOn == true
{
// this is the code causing the error
timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(clickClass.repeatSound), userInfo: nil, repeats: true)
print("play")
}
else
{
timer.invalidate()
clickClass.stopSound()
print("pause")
}
}
}
}
我希望应用每秒播放一次声音。 错误是:
2019-06-13 22:49:38.226089-0700 Metronome[6695:2566182] -[Metronome.ViewController repeatSound]: unrecognized selector sent to instance 0x145e11dc0
2019-06-13 22:49:38.229502-0700 Metronome[6695:2566182] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[Metronome.ViewController repeatSound]: unrecognized selector sent to instance 0x145e11dc0'
*** First throw call stack:
(0x18144127c 0x18061b9f8 0x18135dab8 0x1adc27f60 0x181446ac4 0x18144875c 0x181ec88a4 0x1813d3650 0x1813d3380 0x1813d2bb4 0x1813cdb04 0x1813cd0b0 0x1835cd79c 0x1adbfc978 0x100ffccf0 0x180e928e0)
libc++abi.dylib: terminating with uncaught exception of type NSException
连同Thread 1: signal SIGABRT
您向计时器传递了错误的目标。你想传递 clickClass
,而不是 self
。并且选择器不应该引用变量,它应该引用 class.
timer = Timer.scheduledTimer(timeInterval: 1, target: clickClass, selector: #selector(playSound.repeatSound), userInfo: nil, repeats: true)
您还应注意正确命名。 Class、结构和枚举名称应以大写字母开头。变量、函数和案例名称应以小写字母开头。
您在代码中为计时器设置的目标不正确。将目标更改为 self.clickClass
,如下所示:
timer = Timer.scheduledTimer(timeInterval: 1, target: self.clickClass, selector: #selector(clickClass.repeatSound), userInfo: nil, repeats: true)
对于 self
目标,应用程序会尝试在同一个 viewcontroller 中找到 repeatSound
方法。另请遵循以下 link 以获取 swift 命名约定的最佳实践: