如何移除Swift音频录制代码中的强制解包操作?
移除Swift音频录制代码中的强制解包操作
我来帮你一步步把代码里的强制解包都去掉,让代码更健壮、更安全~先看你给出的原始代码,里面有几处!强制解包,这些操作很容易触发运行时崩溃,我们可以用Swift的可选绑定、可选链来替换它们。
原始代码
var recorder : Recorder? = nil func startAudioRecording() { if recorder == nil { recorder = Recorder() } if !recorder!.isRunning() { recorder?.startRecording({ [weak self] audioData in self?.remoteInterface?.sendVoice(audioData.0) }, withCompletionBlock: { (_) in }) } } func stopAudioRecording(_ keyCommand: String!){ if let _ = recorder { if(recorder?.isRunning())! { recorder?.stopRecording(completionBlock: { (isFinished: Bool) in DispatchQueue.global().asyncAfter(deadline: DispatchTime.now() + Double(Int64(1 * NSEC_PER_MSEC)) / Double(NSEC_PER_SEC), execute: { [unowned self] in self.remoteInterface?.sendTouchUp(keyCommand) self.audioRecorder = nil // 这里应该是笔误,原变量名是recorder }) }) } } }
逐点修改说明
处理
startAudioRecording中的强制解包:
原代码里if !recorder!.isRunning()直接强制解包recorder,我们可以用可选绑定先确保recorder存在,再检查运行状态,这样既安全又清晰:guard let recorder = recorder else { return } if !recorder.isRunning() { recorder.startRecording({ [weak self] audioData in self?.remoteInterface?.sendVoice(audioData.0) }, withCompletionBlock: { (_) in }) }处理
stopAudioRecording中的强制解包:
原代码里if(recorder?.isRunning())!的强制解包同样危险,我们可以用guard语句一次性完成「recorder存在」和「正在运行」两个条件的检查,不符合就直接返回,代码逻辑更紧凑:guard let recorder = recorder, recorder.isRunning() else { return } recorder.stopRecording(completionBlock: { [unowned self] isFinished in DispatchQueue.global().asyncAfter(deadline: .now() + 0.001) { self.remoteInterface?.sendTouchUp(keyCommand) self.recorder = nil // 修正笔误,把audioRecorder改成recorder } })另外还简化了延迟执行的语法,让代码更易读。
修改后的完整代码
var recorder: Recorder? = nil func startAudioRecording() { if recorder == nil { recorder = Recorder() } // 可选绑定避免强制解包 guard let recorder = recorder else { return } if !recorder.isRunning() { recorder.startRecording({ [weak self] audioData in self?.remoteInterface?.sendVoice(audioData.0) }, withCompletionBlock: { (_) in }) } } func stopAudioRecording(_ keyCommand: String!) { // 一次性检查recorder状态,不符合直接返回 guard let recorder = recorder, recorder.isRunning() else { return } recorder.stopRecording(completionBlock: { [unowned self] isFinished in DispatchQueue.global().asyncAfter(deadline: .now() + 0.001) { self.remoteInterface?.sendTouchUp(keyCommand) self.recorder = nil } }) }
现在代码里已经没有任何强制解包操作了,运行时的崩溃风险大大降低,同时可读性也更好~
内容的提问来源于stack exchange,提问作者Sanoj Kashyap
相关产品推荐
相关产品推荐

