import SwiftUI struct AsyncImageView: View { let url: String let nums: [Int] let index: Int @State private var image: UIImage? @State private var isLoading = false @State private var error: Error? // 静态属性,用于维护当前加载的索引范围 private static var currentlyLoadingIndices: Set = [] private static let maxConcurrentLoads = 4 var body: some View { Group { if let image = image { Image(uiImage: image) .resizable() .aspectRatio(contentMode: .fit) } else if isLoading { ProgressView() } else if error != nil { VStack { Image(systemName: "exclamationmark.triangle") .foregroundColor(.red) Text(error?.localizedDescription ?? "未知错误") .font(.caption) } } else { Color.gray.opacity(0.3) } } .onAppear { loadImage() } } private func loadImage() { // 如果已经在加载中,或者超出最大加载限制,直接返回 guard !Self.currentlyLoadingIndices.contains(index), Self.currentlyLoadingIndices.count < Self.maxConcurrentLoads else { return } // 添加当前索引到加载集合 Self.currentlyLoadingIndices.insert(index) isLoading = true error = nil // 确保 nums 和 index 对齐,避免越界 guard let decodeNum = nums[safe: index] else { print("错误:nums 中未找到索引 \(index) 对应的值,可能 API 数据不一致") Self.currentlyLoadingIndices.remove(index) return } print("调试信息:图片 URL: \(url), 解密参数 num: \(decodeNum), 索引: \(index)") guard let imageUrl = URL(string: url) else { self.error = NSError(domain: "无效的URL", code: 1, userInfo: nil) isLoading = false Self.currentlyLoadingIndices.remove(index) return } // 加载图片数据 URLSession.shared.dataTask(with: imageUrl) { data, response, error in DispatchQueue.main.async { // 移除当前索引 Self.currentlyLoadingIndices.remove(index) self.isLoading = false if let error = error { self.error = error print("图片加载失败,错误: \(error.localizedDescription)") return } guard let httpResponse = response as? HTTPURLResponse, (200...299).contains(httpResponse.statusCode), let data = data, !data.isEmpty else { self.error = NSError(domain: "无效响应", code: 2, userInfo: nil) print("图片加载失败,无效响应或数据为空") return } if let loadedImage = UIImage(data: data) { print("图片加载成功,开始解密...") let decodedImage = loadedImage.decodeImage(num: decodeNum) self.image = decodedImage print("解密完成,图片已更新") } else { self.error = NSError(domain: "图片数据解码失败", code: 4, userInfo: nil) print("图片数据解码失败") } } }.resume() } } extension Array { subscript(safe index: Int) -> Element? { return indices.contains(index) ? self[index] : nil } }