解决结构体/TableView Cell中无法弹窗的问题:JSON解析异常时如何触发弹窗提示
解决结构体/TableView Cell中无法弹窗的问题:JSON解析异常时如何触发弹窗提示
兄弟,你踩的这个坑我之前也遇到过——结构体本身不是UI组件,根本拿不到present方法的上下文,所以直接在里面写弹窗肯定行不通。咱们换个思路,把弹窗的活儿交给管TableView的SearchPoi类来干,结构体只负责解析数据和传递状态就行,具体操作看下面:
第一步:改造结构体的解析方法,通过闭包传递弹窗需求
把原来只负责解析的方法,加一个专门的回调闭包,用来通知外部“需要弹窗”的状态,同时把弹窗需要的标题、消息传出去:
struct SearchApi { // 注意Swift命名规范,结构体首字母大写哦 static var dataFromSearchApi: [YourResultModel]? // 替换成你的实际结果类型 func newParseJSON(poiData: Data, completionHandler: @escaping () -> Void, alertHandler: @escaping (String, String) -> Void) { let decoder = JSONDecoder() do { let decodedData = try decoder.decode(POIData.self, from: poiData) // 检查解析结果是否为空 guard let validResults = decodedData.results, !validResults.isEmpty else { // 结果为空,触发弹窗回调 alertHandler("Json Empty", "未获取到有效数据,请重试") completionHandler() return } SearchApi.dataFromSearchApi = validResults completionHandler() } catch { // 解析失败时也可以触发弹窗,把错误信息传出去 alertHandler("解析失败", error.localizedDescription) print(error) } } }
第二步:在SearchPoi类中实现弹窗逻辑
因为SearchPoi是ViewController,拥有present方法的上下文,所以在这里处理弹窗是最合理的。调用结构体的解析方法时,把弹窗的逻辑写在alertHandler里:
class SearchPoi: UIViewController, UITableViewDataSource, UITableViewDelegate { // 你的TableView实例、数据源等代码... // 假设这是你触发数据解析的方法 func loadAndParsePoiData() { // 先获取到要解析的poiData(比如从网络请求或者本地文件读取) guard let poiData = getPoiData() else { return } let searchApi = SearchApi() searchApi.newParseJSON(poiData: poiData, completionHandler: { [weak self] in // 解析成功后刷新TableView self?.tableView.reloadData() }, alertHandler: { [weak self] title, message in // 这里写弹窗逻辑,因为在ViewController里,所以可以正常调用present let dialogMessage = UIAlertController(title: title, message: message, preferredStyle: .alert) let okAction = UIAlertAction(title: "OK", style: .default) { _ in print("Ok button tapped") } dialogMessage.addAction(okAction) self?.present(dialogMessage, animated: true) }) } // 模拟获取poiData的方法,根据你的实际情况替换 private func getPoiData() -> Data? { // 你的数据获取逻辑... return nil } }
额外提醒
- 尽量遵循Swift的命名规范,比如结构体、类名首字母大写,方法名小驼峰,这样代码可读性更高。
- 结构体的职责应该聚焦在数据处理上,UI相关的逻辑(弹窗、页面跳转等)都交给ViewController或者专门的UI管理类,这样代码的职责更清晰,也避免了上下文缺失的问题。
- 用
[weak self]避免循环引用,这是闭包回调里的常规操作,防止内存泄漏。
备注:内容来源于stack exchange,提问作者submariner
相关产品推荐
相关产品推荐

