You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何移除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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 03:58:48