Как правильно инициализировать нелокальный неизменный чей бросок init ()? - PullRequest
0 голосов
/ 25 января 2019

С учетом этих фактов:

1) Лучше инициализировать объекты как let (неизменяемые), а не var, когда это возможно.

2) Некоторые объекты могут выдавать, когда вы вызываете их инициализатор (такие как AVAudioPlayer, , например ).

3) Некоторые объекты имеют инициализаторы, которые требуют аргументов, которые недоступны до «self доступен», еще раз, например, AVAudioPlayer, поэтому, если оничтобы быть классовым / нелокальным let, то они должны быть инициализированы не до или после, а только внутри init ().

Так, например, допустим, у нас есть класс, в который мы хотимопределить свойство уровня класса типа AVAudioPlayer (или любого другого объекта, чей метод init вызывает), но мы хотим, чтобы оно было разрешено.

После долгих проб и ошибок, согласовывая свой обход предупреждений X-кода,и экспериментируя с опциями, лучшее, что я придумал (с помощью), это:

import AVFoundation

class MySoundPoolPlayer {

    private let dingURL = Bundle.main.url(forResource: "ding", withExtension: "wav")
    private let dongURL = Bundle.main.url(forResource: "dong", withExtension: "wav")

    private let dingPlayer: AVAudioPlayer?
    private let dongPlayer: AVAudioPlayer?

    init() {

        dingPlayer = try? AVAudioPlayer(contentsOf: dingURL!)
        dongPlayer = try? AVAudioPlayer(contentsOf: dongURL!)

    }

    func playDing() {
        dingPlayer!.play()
    }

    func playDong() {
        dongPlayer!.play()
    }

    func stopAllSounds() {
        dingPlayer!.stop()
        dongPlayer!.stop()
    }

}

Итак, теперь в основном у нас есть неизменное значение, которое может быть нулевым, если AVAudioPlayer.init () выбрасывает ... но, по крайней мере, это let, и, поскольку оно установлено как необязательное, приложение не будет аварийно завершать работу, если AVAudioPlayer.init () выбрасывает.

Есть ли лучший способделать это?

Как лучше всего инициализировать объекты этих типов (как на уровне класса)?

Большое спасибо за ваше время и внимание!XD

1 Ответ

0 голосов
/ 25 января 2019

В основном у вас есть три варианта:

  1. принудительная попытка (try!), если вы на 100% уверены, что AVAudioPlayer будет успешным. Обратите внимание, однако, что даже если в URL-адресе есть допустимое содержимое, инициализатор все равно может завершиться ошибкой из-за некоторых других внутренних условий
  2. пометьте свойства как дополнительные (как вы это сделали), это защитит вас от сбоев, но увеличит сложность остальной части вашего кода, так как вам нужно будет всегда разворачивать свойства.
  3. отметьте ваш инициализатор как бросающий. Это переместит вверх бремя обработки ошибок, но в какой-то момент вам, вероятно, придется использовать подходы # 1 / # 2.

Все вышеперечисленные решения где-то требуют компромисса, так как рано или поздно вам придется обрабатывать ошибки инициализации. Вопрос в том, как вы хотите это сделать:

  • сбой приложения, поскольку AVAudioPlayer ошибка не может быть исправлена ​​в вашем приложении
  • обрабатывает ошибку инициализации и предоставляет другой путь через приложение
  • тихо игнорирует сбои и продолжает работать с приложением

И все это зависит от специфики вашего приложения.

...