简体   繁体   中英

Terminating With Uncaught Exception Of Type NSException Timer Swift Crash

I am trying to use the timer class in swift, but my app keeps crashing with the signal SIGBART and also terminating with uncaught exception of type NSException errors. Please help. Thanks.

I have narrowed it down to being because of my timer, but I do not know how to fix it.

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")
        }
    }
}

}

I expect the app to play the sound every second. The is the error is:

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

along with Thread 1: signal SIGABRT

You are passing the wrong target to the timer. You want to pass clickClass , not self . And the selector should not reference the variable, it should reference the class.

timer = Timer.scheduledTimer(timeInterval: 1, target: clickClass, selector: #selector(playSound.repeatSound), userInfo: nil, repeats: true)

You should also take care to name things properly. Class, struct, and enum names should start with uppercase letters. Variable, function, and case names should start with lowercase letters.

The target set in your code for timer is incorrect. Change the target to self.clickClass as below :

timer = Timer.scheduledTimer(timeInterval: 1, target: self.clickClass, selector: #selector(clickClass.repeatSound), userInfo: nil, repeats: true)

With self target the application tries to find the repeatSound method in the same viewcontroller. Also please follow below link for the best practices for swift naming conventions :

https://github.com/raywenderlich/swift-style-guide

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM