Обмен данными между классами swift

#swift

#swift

Вопрос:

У меня есть этот класс с именем AudioController() , и у него есть переменная с именем sources , которая представляет собой массив строк.

AudioViewController() код:

 import Foundation

class AudioController {
    static let shared = AudioController()
    var sources = [String]()

    init() {
      print("Sources: (sources)")
      let controller = RemoteCommandController()
      player = QueuedAudioPlayer(remoteCommandController: controller)
      player.remoteCommands = [
        .stop,
        .play,
        .pause,
        .togglePlayPause,
        .next,
        .previous,
        .changePlaybackPosition
      ]
      try? audioSessionController.set(category: .playback)
      try? player.add(items: sources, playWhenReady: false) // fatal error here because sources is nil
    }
}
  

Но. С другой стороны, viewcontroller при попытке передать sources :

 AudioController().sources = ["Shakira"]
  

Я получаю:

Неустранимая ошибка: неожиданно обнаружено значение nil при развертывании необязательного значения

и print("Sources: (sources)") возвращает sources [] .

Комментарии:

1. 1. Замените AudioController() на AudioController.shared . 2. Покажите фактическую строку кода, вызывающую ошибку.

2. sources не может быть nil в этой строке. И опубликованный вами код не будет компилироваться. Где player объявлено?

Ответ №1:

На самом деле, здесь есть странные вещи: зачем вам общий экземпляр, если вы его не используете? И затем, вы пытаетесь воспроизвести пустой массив, возможно, в этом проблема. Попробуйте указать значения перед запуском проигрывателя

 class AudioController {
    static let shared = AudioController()
    var sources: [String]

    init(sources: [String]) {
      self.sources = sources
      print("Sources: (sources)")
      let controller = RemoteCommandController()
      player = QueuedAudioPlayer(remoteCommandController: controller)
      player.remoteCommands = [
        .stop,
        .play,
        .pause,
        .togglePlayPause,
        .next,
        .previous,
        .changePlaybackPosition
      ]
      try? audioSessionController.set(category: .playback)
      try? player.add(items: self.sources, playWhenReady: false) // fatal error here because sources is nil
    }
}

// then instantiate the controller with sources
AudioController(sources: ["Shakira"])
  

Однако я предлагаю вам пересмотреть свой дизайн. Возможно, это не очень хорошая идея начинать играть в init .

Ответ №2:

Если вы хотите использовать общий экземпляр (что, я думаю, вы делаете), используйте что-то вроде этого:

 AudioController.shared.sources = ["Shakira"]
  

Вероятно, вам также следует добавить private init() {} , чтобы предотвратить случайную инициализацию AudioController. Это создаст частный инициализатор, который нельзя использовать вне AudioController.

Оператор print всегда будет печатать [] потому что при вызове функции init в массиве еще ничего нет.

Комментарии:

1. @rmaddy верно, однако я подозреваю, что это результат неправильного использования общего ресурса (связанного с кодом, который мы не видим)