Похоже, что ваша структура, чтобы стать полностью инстанцированной, должна сначала дождаться выполнения двух асинхронных задач с данными (выборка изображений). Поскольку вы запускаете их, но не ждете их завершения, в момент времени, когда вы пишете в массив, данные изображения просто еще не доступны.
Существует несколько возможных способов решения. этот вид временной зависимости. Какой из них подходит для вашего проекта, во многом зависит от вашего варианта использования и общего выбора архитектуры.
В целом, однако, было бы хорошей идеей не допускать такие асинхронные задачи с данными вне структуры init
, и вместо этого выполняйте их в любом классе, который отвечает за создание и управление вашими структурами. Затем извлеченные изображения могут быть переданы в структуру в качестве параметров инициализации.
Вот как вы могли бы go рассказать об этом, продемонстрировав это немного отвлеченно:
Возможно, вы в данный момент находитесь где-то в вашем закодируйте объект с помощью функции, которая создает и хранит MyStruct
s, аналогичный следующему:
func loadMyStruct() {
self.myStruct = MyStruct(...)
}
Лучшей альтернативой этой функции создания структуры будет:
func loadMyStruct(completion: @escaping ()->Void) {
DispatchQueue(label: "MyStructDataFetch", attributes: .concurrent).async { [weak self] in // don't block main thread waiting for data tasks to finish
let dispatchGroup = DispatchGroup() // since we're waiting on two parallel async tasks, we can use a DispatchGroup to group them together
var imageA: UIImage?
var imageB: UIImage?
dispatchGroup.enter() // enter DispatchGroup
let refA = Storage.storage().reference().child("Images").child(todayDate).child(DID)
refA.getData(maxSize: 1000 * 1240 * 1240) { data, error in // start 1st data task
if let error = error {
...
} else {
imageA = UIImage(data: data!)!
}
dispatchGroup.leave() // 1st task is done; leave DispatchGroup
}
dispatchGroup.enter() // enter DispatchGroup
let refB = Storage.storage().reference().child("Icons").child(RID)
refB.getData(maxSize: 1000 * 1240 * 1240) { data, error in // start 2nd data task
if let error = error {
...
} else {
imageB = UIImage(data: data!)!
}
dispatchGroup.leave() // 2nd task is done; leave DispatchGroup
}
let _ = dispatchGroup.wait(timeout: DispatchTime.distantFuture) // wait for all tasks to be done, then...
self?.myStruct = MyStruct(imageA: imageA, imageB: imageB, ...) // ... pass the finished images to MyStruct constructor
completion() // Optional: notify observer (e.g. UI) that "MyStruct" is now ready to use
}
}
init структуры изменен соответственно:
init?(imageA: UIImage?, imageB: UIImage?, ...) {
...