DispatchSource.makeTimerSource当按下后退按钮时崩溃应用程序Swift

我已经实现了使用DispatchSource和计时器工作的录制音频(录制和播放工作正常)的计时器,但是当我按下我的导航控制器选项卡上的后退按钮时,应用程序崩溃。我可以毫无问题地前进到下一个屏幕。 错误:线程1:EXC_BAD_INSTRUCTION(code = EXC_I386_INVOP,subcode = 0x0)DispatchSource.makeTimerSource当按下后退按钮时崩溃应用程序Swift

有人请给我一个暗示,为什么这是?

我的看法控制器代码:

import Foundation 

import UIKit

import AVFoundation

class RecordGreetingController: UIViewController {

@IBOutlet weak var timeLabel: UILabel!

var audioPlayer: AVAudioPlayer!

var updateTimer = DispatchSource.makeTimerSource(flags: [], queue: DispatchQueue.main)

override func viewDidLoad() {

super.viewDidLoad()

}

@IBAction func toggleRecordButton(_ sender: UIButton) {

if AudioRecorderManager.shared.recorder == nil {

if AudioRecorderManager.shared.recordAudio(fileName: "NewRecording") {

updateTimer.resume()

}

let formatter = DateComponentsFormatter()

formatter.zeroFormattingBehavior = .pad

formatter.includesApproximationPhrase = false

formatter.allowedUnits = [.minute, .second]

formatter.calendar = Calendar.current

updateTimer.schedule(deadline: DispatchTime.now(), repeating: DispatchTimeInterval.milliseconds(100))

updateTimer.setEventHandler { [weak self] in

self?.timeLabel.text = formatter.string(from: AudioRecorderManager.shared.recorder!.currentTime)

}

}

else {

AudioRecorderManager.shared.finishRecording()

AudioRecorderManager.shared.recorder = nil

updateTimer.suspend()

}

}

}

我AudioRecorderManager类:

import Foundation 

import AVFoundation

class AudioRecorderManager: NSObject, AVAudioRecorderDelegate {

static let shared = AudioRecorderManager()

var recordingSession: AVAudioSession!

var recorder: AVAudioRecorder?

func setup() {

recordingSession = AVAudioSession.sharedInstance()

do {

try recordingSession.setCategory(AVAudioSessionCategoryPlayAndRecord, with: .defaultToSpeaker)

try recordingSession.setActive(true)

// Request permission from user

recordingSession.requestRecordPermission{ (allowed) in

if allowed {

print("Mic authorised")

}

else {

print("Mic not authorised")

// TODO display alert to allow microphone access in settings to operate

}

}

}

catch {

print("Failed to set category", error.localizedDescription)

}

}

var meterTimer: Timer?

var recorderApc0: Float? = 0

var recorderPeak0: Float? = 0

// Starts the recording session

func recordAudio(fileName:String) -> Bool {

let url = getUserPath().appendingPathComponent(fileName+".m4a")

let audioURL = URL.init(fileURLWithPath: url.path)

let recordSettings: [String: Any] = [

AVFormatIDKey: NSNumber(value: kAudioFormatAppleLossless),

AVEncoderAudioQualityKey: AVAudioQuality.high.rawValue,

AVEncoderBitRateKey: 12000.0,

AVNumberOfChannelsKey: 1,

AVSampleRateKey: 44100.0

]

do {

recorder = try AVAudioRecorder(url: audioURL, settings: recordSettings)

recorder?.delegate = self

recorder?.isMeteringEnabled = true

recorder?.prepareToRecord()

recorder?.record()

self.meterTimer = Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true, block: { (timer: Timer) in

// Update recorder meter values

if let recorder = self.recorder {

recorder.updateMeters()

self.recorderApc0 = recorder.averagePower(forChannel: 0)

self.recorderPeak0 = recorder.peakPower(forChannel: 0)

}

})

print("Recording")

return true

}

catch {

print("Error recording")

return false

}

}

// Stop recording

func finishRecording() {

self.recorder?.stop()

self.meterTimer?.invalidate()

}

// Gets path for the folder the file is being saved to

func getUserPath() -> URL {

return FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]

}

func audioRecorderDidFinishRecording(_ recorder: AVAudioRecorder, successfully flag: Bool) {

print("Audio Manager did finish recording", flag)

}

func audioRecorderEncodeErrorDidOccur(_ recorder: AVAudioRecorder, error: Error?) {

print("Error encoding ", error?.localizedDescription ?? "")

}

}

回答:

这最终被解决我的问题。忽略来自上述两个谁没有解决这个问题的一个心怀不满的向下投票:

var updateTimer: DispatchSourceTimer? 

@IBOutlet weak var timeLabel: UILabel!

func startTimer() {

let formatter = DateComponentsFormatter()

formatter.zeroFormattingBehavior = .pad

formatter.includesApproximationPhrase = false

formatter.allowedUnits = [.minute, .second]

formatter.calendar = Calendar.current

let queue = DispatchQueue.main

updateTimer = DispatchSource.makeTimerSource(queue: queue)

updateTimer!.schedule(deadline: .now(), repeating: .milliseconds(100))

updateTimer!.setEventHandler { [weak self] in

self?.timeLabel.text = formatter.string(from: AudioRecorderManager.shared.recorder!.currentTime)

}

updateTimer!.resume()

}

func stopTimer() {

updateTimer?.cancel()

updateTimer = nil

}

deinit {

self.stopTimer()

}

@IBAction func toggleRecordButton(_ sender: UIButton) {

if AudioRecorderManager.shared.recorder == nil {

if AudioRecorderManager.shared.recordAudio(fileName: "NewRecording") {

startTimer()

}

}

else {

stopTimer()

AudioRecorderManager.shared.finishRecording()

AudioRecorderManager.shared.recorder = nil

}

}

以上是 DispatchSource.makeTimerSource当按下后退按钮时崩溃应用程序Swift 的全部内容, 来源链接: utcz.com/qa/259210.html

回到顶部