主线程调用报错:API请求成功但错误弹窗致应用崩溃
iOS网络请求异常时弹窗崩溃的原因与修复方案
报错原因
URLSession的dataTask闭包默认在后台线程执行。你的代码存在明显的线程处理不一致问题:
- 成功获取数据时,特意用
DispatchQueue.main.async把回调切到了主线程 - 但网络错误、数据解析错误等失败场景,直接在后台线程调用了completion回调
- 而所有UI操作(比如present弹窗)必须在主线程执行,因此调用
showAlertWith时触发了"Call must be made on main thread"崩溃
修复方案
推荐在ApiService层统一处理线程切换,保证所有completion回调都在主线程执行,这样上层VC不需要关心线程问题,代码更健壮。
修改后的ApiService代码
import Foundation class ApiService { private var dataTask: URLSessionDataTask? // MARK: - Get popular movies data func getPopularMoviesData(completion: @escaping (Result<MovieData, Error>) -> Void) { let popularMoviesURL = "https://api.themoviedb.org/3/movie/popular?api_key=4e0be2c22f7268edffde97481d49064a&language=en-US&page=1" guard let url = URL(string: popularMoviesURL) else {return} dataTask = URLSession.shared.dataTask(with: url) { (data, response, error) in // 统一把所有回调切换到主线程 DispatchQueue.main.async { // Handle Error if let error = error { completion(.failure(error)) print("DataTask error: \(error.localizedDescription)") return } guard let response = response as? HTTPURLResponse else { print("Empty Response") // 可选:自定义空响应错误并回调 return } print("Response status code: \(response.statusCode)") guard let data = data else { print("Empty Data") // 可选:自定义空数据错误并回调 return } do { let decoder = JSONDecoder() let jsonData = try decoder.decode(MovieData.self, from: data) completion(.success(jsonData)) } catch let error { completion(.failure(error)) } } } dataTask?.resume() } }
备选方案(仅在VC层临时处理)
如果不想修改ApiService,也可以在VC的失败回调里手动切换到主线程调用弹窗:
private func loadPopularMoviesData() { apiService.getPopularMoviesData { [weak self] (result) in switch result { case .success(let listOf): print(result) case .failure(let error): // 切换到主线程再执行UI操作 DispatchQueue.main.async { self?.showAlertWith(title: "Could not connect!", message: "Please check your internet connection \n or try again later") } print("Error processing json data: \(error)") } } }
额外优化提示
- 修正代码拼写错误:"Plese"改为"Please"
- 空响应、空数据场景建议自定义Error并通过completion回调,让VC可以统一处理所有错误弹窗逻辑
内容的提问来源于stack exchange,提问作者LordGrim
相关产品推荐
相关产品推荐

