Squeak.ru - шаблоны программирования

Swift: AVAudioPlayer не воспроизводится, возможная ошибка с потоками?

В настоящее время я работаю над приложением, которое воспроизводит аудиоклип на основе состояния изображения/объекта.

В настоящее время я получаю этот код ошибки.

Тема 1: EXC_BAD_ACCESS (код = 1, адрес = 0x48)

Я предполагаю, что это может быть ошибка при попытке воспроизвести другой аудиоклип в том же потоке, когда другой аудиоклип уже воспроизведен в том же потоке.

Но, честно говоря, я не уверен, я все еще изучаю потоки и многопоточность, поэтому, вероятно, доберусь сюда.

Что мне здесь не хватает? Как я могу воспроизвести второй аудиоклип (turnSaberOffAudio) без появления этого сообщения об ошибке? Спасибо!

Вот что происходит, когда я нажимаю на кнопку.

@objc func lightsaberTapped() {
    print("lightsaber open!")

    if lightsaberModel.isSaberOn == false {
        UIView.animate(withDuration: 0.2, animations: {
            self.saberImageHeightConstraint.constant = 530
            self.saberImageWidthConstraint.constant = 210
            self.mainView.layoutIfNeeded()
            self.viewDidLayoutSubviews()
        }, completion: nil)
        lightsaberModel.turnSaberOnAudio.play()
        lightsaberModel.isSaberOn = true
    } else {
        UIView.animate(withDuration: 0.2, animations: {
            self.saberImageHeightConstraint.constant = 1
            self.saberImageWidthConstraint.constant = 1
            self.mainView.layoutIfNeeded()
            self.viewDidLayoutSubviews()
        }, completion: nil)
        lightsaberModel.turnSaberOffAudio.play()
        lightsaberModel.isSaberOn = false
    }
}

Это модель с необходимой информацией.

class Model {

    var turnSaberOnAudio: AVAudioPlayer = AVAudioPlayer()
    var turnSaberOffAudio: AVAudioPlayer = AVAudioPlayer()
    var whichLightsaber = String()
    var isSaberOn = Bool()

    func turnSaberOn() {
        let turnSaberOnPath = Bundle.main.path(forResource: "SaberOn", ofType: "wav")
        do {
            turnSaberOnAudio = try AVAudioPlayer(contentsOf: URL(fileURLWithPath: turnSaberOnPath!))
        }
        catch {
            print(error)
        }
    }

    func turnSaberOff() {
        let turnSaberOffPath = Bundle.main.path(forResource: "SaberOff", ofType: "mp3")
        do {
            turnSaberOffAudio = try AVAudioPlayer(contentsOf: URL(fileURLWithPath: turnSaberOffPath!))
        }
        catch {
            print(error)
        }
    }
}

Ответы:


1

Это то, чего вы никогда не должны делать:

var turnSaberOnAudio: AVAudioPlayer = AVAudioPlayer()

Пустой инициализатор AVAudioPlayer() создает что-то бесполезное, что не только бесполезно, но и вредно, чтобы вызвать сбой.

И объявив переменную как необязательную, вы не сможете отличить, содержит ли она что-то полезное или нет.


И с вашим текущим кодом turnSaberOn() или turnSaberOff() могут не вызываться при вызове play().

Попробуйте изменить Model как:

class Model {

    var turnSaberOnAudio: AVAudioPlayer? //<- Never use `AVAudioPlayer()`
    var turnSaberOffAudio: AVAudioPlayer? //<- Never use `AVAudioPlayer()`
    var whichLightsaber: String = ""
    var isSaberOn: Bool = false

    init() {
        let turnSaberOnUrl = Bundle.main.url(forResource: "SaberOn", withExtension: "wav")!
        do {
            turnSaberOnAudio = try AVAudioPlayer(contentsOf: turnSaberOnUrl)
            turnSaberOnAudio!.prepareToPlay()
            print("\(turnSaberOnUrl) loaded")
        } catch {
            print(error)
        }
        let turnSaberOffUrl = Bundle.main.url(forResource: "SaberOff", withExtension: "mp3")!
        do {
            turnSaberOffAudio = try AVAudioPlayer(contentsOf: turnSaberOffUrl)
            turnSaberOffAudio!.prepareToPlay()
            print("\(turnSaberOffUrl) loaded")
        } catch {
            print(error)
        }

        //...
    }

    //...
}

И используйте это так:

    @IBAction func lightSaberTapped(_ sender: Any) {
        print("lightsaber open!")

        if !lightsaberModel.isSaberOn {
            //...
            lightsaberModel.turnSaberOnAudio?.play()
            lightsaberModel.isSaberOn = true
        } else {
            //...
            lightsaberModel.turnSaberOffAudio?.play()
            lightsaberModel.isSaberOn = false
        }
    }
09.05.2019
Новые материалы

Угловая структура архитектуры
Обратите внимание, что эта статья устарела, я решил создать новую с лучшей структурой и с учетом автономных компонентов: https://medium.com/@marekpanti/angular-standalone-architecture-b645edd0d54a..

«Данные, которые большинство людей используют для обучения своих моделей искусственного интеллекта, поставляются со встроенным…
Первоначально опубликовано HalkTalks: https://hacktown.com.br/blog/blog/os-dados-que-a-maioria-das-pessoas-usa-para-treinar-seus-modelos-de-inteligencia-artificial- ja-vem-com-um-vies-embutido/..

Сильный ИИ против слабого ИИ: различия парадигм искусственного интеллекта
В последние годы изучению и развитию искусственного интеллекта (ИИ) уделяется большое внимание и прогресс. Сильный ИИ и Слабый ИИ — две основные парадигмы в области искусственного интеллекта...

Правильный способ добавить Firebase в ваш проект React с помощью React Hooks
React + Firebase - это мощная комбинация для быстрого и безопасного создания приложений, от проверки концепции до массового производства. Раньше (знаете, несколько месяцев назад) добавление..

Создайте API с помощью Python FastAPI
Создание API с помощью Python становится очень простым при использовании пакета FastAPI. После установки и импорта вы можете создать приложение FastAPI и указать несколько конечных точек. Каждой..

Веселье с прокси-сервером JavaScript
Прокси-серверы JavaScript — это чистый сахар, если вы хотите создать некоторую общую логику в своих приложениях, чтобы облегчить себе жизнь. Вот один пример: Связь клиент-сервер Мы..

Получить бесплатный хостинг для разработчиков | Разместите свой сайт за несколько шагов 🔥
Статические веб-сайты — это веб-страницы с фиксированным содержанием и его постоянным содержанием. Но теперь статические сайты также обрабатывают динамические данные с помощью API и запросов...