Swift新手求助:如何全局访问videoLink无需重复调用fetchBroadcasts
解决方案:缓存数据实现全局访问
Hey there!作为Swift初学者,你的思路已经很清晰啦,咱们来一步步解决这个不用重复调用网络请求就能全局访问videoLink的问题~
核心思路是在你的BroadService单例里缓存解析后的Games数据,这样后续需要获取videoLink时直接读取缓存即可,不用每次都发起网络请求。
修改后的完整代码
struct Games: Decodable { let videoLink: String } class BroadService { // 保持单例模式不变 static let sharedInstance = BroadService() // 新增:私有属性,用来缓存解析后的Games数组 private var cachedGames: [Games]? // 新增:线程锁,保证多线程环境下缓存访问的安全性 private let lock = NSLock() // 优化fetch方法:支持强制刷新,优先返回缓存 func fetchBroadcasts(forceRefresh: Bool = false, completion: @escaping ([Games]?) -> ()) { // 如果有缓存且不需要强制刷新,直接返回缓存内容 if !forceRefresh, let cachedGames = self.cachedGames { completion(cachedGames) return } let jsonUrlString = "LINK IS HERE." guard let url = URL(string: jsonUrlString) else { completion(nil) return } URLSession.shared.dataTask(with: url) { [weak self] (data, response, error) in guard let self = self else { return } guard let data = data else { print("Failed to get data from network") completion(nil) return } do { let games = try JSONDecoder().decode([Games].self, from: data) // 加锁更新缓存,避免多线程竞态问题 self.lock.lock() self.cachedGames = games self.lock.unlock() completion(games) } catch let jsonError { print("Error deserializing JSON: \(jsonError.localizedDescription)") completion(nil) } }.resume() } // 新增:直接从缓存获取指定索引的videoLink func getVideoLink(at index: Int) -> String? { // 加锁读取缓存,保证线程安全 lock.lock() defer { lock.unlock() } guard let games = cachedGames, index >= 0, index < games.count else { return nil } return games[index].videoLink } }
怎么使用?
首次加载/刷新数据:
还是用你原来的方式调用fetchBroadcasts,如果需要强制刷新最新数据(比如下拉刷新),可以传forceRefresh: true:BroadService.sharedInstance.fetchBroadcasts(forceRefresh: true) { games in // 这里可以做UI更新等操作 if let games = games { print("Loaded \(games.count) broadcasts") } }全局访问videoLink:
之后任何地方需要获取指定索引的videoLink,直接调用缓存读取方法即可,不用再发起网络请求:// 比如在tableView的cellForRow里 if let videoLink = BroadService.sharedInstance.getVideoLink(at: indexPath.row) { // 使用videoLink做你需要的操作,比如加载视频 print("Video link: \(videoLink)") }
关键细节说明
- 线程安全:加入
NSLock是因为网络请求的回调在后台线程,而UI线程可能同时读取缓存,加锁可以避免多线程访问时的竞态条件,防止数据错乱。 - 缓存边界处理:
getVideoLink方法里做了索引越界判断,避免数组越界崩溃。 - 灵活性:
forceRefresh参数让你可以主动触发数据更新,兼顾缓存效率和数据新鲜度。
如果你还有其他疑问,比如想实现缓存过期机制(比如缓存超过1小时就自动刷新),随时问哦~
内容的提问来源于stack exchange,提问作者George Constantine
相关产品推荐
相关产品推荐

