[英]Issue while downloading images from server
我從服務器收到了一個數組 object,然后我想下載該 object 上具有一個屬性的圖像。 然后我想用數組對象和圖像(視圖模型)更新 UI。 我正在后台線程上下載圖像,但我得到的圖像有延遲,並且 object 根本沒有填充,我做錯了什么?
func presentCoinse(_ list: Home.Models.CoinseListResponse) {
var coins = [Home.Models.coinsViewModel]()
for item in list {
getImage(symbol: item.symbol) { image in
let i = Home.Models.coinsViewModel(image: image,
symbol: item.symbol,
name: item.name,
buyPrice: item.buyPrice,
sellPrice: item.sellPrice,
change24Hource: item.symbol)
coins.append(i)
}
}
viewController?.displayCoinsList(viewModel: coins)
}
private func getImage(symbol: String, complation: @escaping(_ image: Data?) -> Void) {
queue.async {
if let url = URL(string: "\(CDN_URL)\(symbol).png") {
let data = try? Data(contentsOf: url)
DispatchQueue.main.async {
complation(data)
}
}
}
}
請注意,您將硬幣設置為空列表,然后使用該空列表調用 displayCoinstList。 該列表以異步方式附加和更新。 您應該觸發視圖 controller 以在准備好后重新加載硬幣列表。 我會在拍攝圖像之前制作硬幣清單,然后在收到圖像后 - UIImageView 將自行渲染。
func presentCoinse(_ list: Home.Models.CoinseListResponse) {
// async part srarts here
var coins = [Home.Models.coinsViewModel]()
for item in list {
getImage(symbol: item.symbol) { image in
let i = Home.Models.coinsViewModel(image: image,
symbol: item.symbol,
name: item.name,
buyPrice: item.buyPrice,
sellPrice: item.sellPrice,
change24Hource: item.symbol)
coins.append(i)
}
}
// async part ends here
viewController?.displayCoinsList(viewModel: coins)
}
你所做的相當於:
func presentCoinse(_ list: Home.Models.CoinseListResponse) {
var coins = [Home.Models.coinsViewModel]()
viewController?.displayCoinsList(viewModel: coins) // coins in empty at this point)
for item in list {
getImage(symbol: item.symbol) { image in
let i = Home.Models.coinsViewModel(image: image,
symbol: item.symbol,
name: item.name,
buyPrice: item.buyPrice,
sellPrice: item.sellPrice,
change24Hource: item.symbol)
coins.append(i)
}
}
}
getImage
方法包含異步操作,在這種情況下,閉包將在方法返回后被調用。 而且,方法displayCoinsList(viewModel:)
在每個異步getImage
之前被調用。
您可以使用調度組 class。
func presentCoinse(_ list: Home.Models.CoinseListResponse) {
var coins = [Home.Models.coinsViewModel]()
let dispatchGroup = DispatchGroup() // add a dispatch group
for item in list {
dispatchGroup.enter() // increment group counter before async call
getImage(symbol: item.symbol) { image in
defer {
dispatchGroup.leave() // decrease group counter in every condition with 'defer'
}
let i = Home.Models.coinsViewModel(image: image,
symbol: item.symbol,
name: item.name,
buyPrice: item.buyPrice,
sellPrice: item.sellPrice,
change24Hource: item.symbol)
coins.append(i)
}
}
dispatchGroup.notify(queue: .main) {
// wait all async calls are completed
viewController?.displayCoinsList(viewModel: coins)
}
}
private func getImage(symbol: String, complation: @escaping(_ image: Data?) -> Void) {
queue.async {
if let url = URL(string: "\(CDN_URL)\(symbol).png") {
let data = try? Data(contentsOf: url)
complation(data)
} else {
complation(nil)
}
}
}
注意:在getImage
方法中需要在每種情況下調用complation
。 如果您忘記調用它,DispatchGroup 將無法收到通知,您將被阻止。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.