You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为什么我的DateTask代码块不运行,无法获取服务器返回数据填充数组

问题原因
  • URLSession实例为局部变量,生命周期过短:当前你将URLSession实例定义在fetchNewsData函数内部,函数执行到task.resume()之后就走完了流程,局部session实例没有被强引用持有,会被ARC立即释放,后续网络请求完成后没有对应的session对象触发回调闭包,因此你打在回调里的断点完全不会触发,这是最常见的触发原因。
  • ATS安全策略限制:如果你的请求地址是HTTP协议而非HTTPS,iOS默认的App Transport Security策略会拦截请求,这种情况也可能导致回调不触发,同时控制台会输出ATS相关的报错日志。
  • 如果你实际使用的urlString存在未编码的特殊字符(比如中文、空格、特殊符号),会导致URL(string: urlString)初始化失败,函数直接走guard let的else分支return,不过你提到let session位置的断点可以触发,所以该可能性可以排除。
修复方案
  1. 首先将URLSession实例改为类的全局持有的属性,不要放在函数内部作为局部变量,同时优化回调逻辑、增加主线程切换适配UI操作:
// 在当前类的属性区域定义全局session,被当前类强引用持有
private let session = URLSession(configuration: .default)

func fetchNewsData(forCoutry country: String, category: String, complition: @escaping (NewsDataModel?) -> ()) {
    let urlString = "替换为你的实际请求地址"
    // 对urlString做编码处理,避免特殊字符导致URL初始化失败
    guard let encodedUrlString = urlString.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed),
          let url = URL(string: encodedUrlString) else {
        complition(nil)
        return
    }
        
    let task = session.dataTask(with: url) {  data, response, error in
        // 先判断error是否存在
        if let error = error {
            print ("ERROR: \(error)")
            complition(nil)
            return
        }
        guard let data = data else {
            complition(nil)
            return
        }
        guard let newsData = self.parseJSON(withData: data) else {
            complition(nil)
            return
        }
        // 回调切回主线程,方便后续填充数组、刷新UI的操作
        DispatchQueue.main.async {
            complition(newsData)
        }
    }
    task.resume()
}
  1. 如果是HTTP请求被ATS拦截的问题,在项目的Info.plist中添加对应配置,放开目标域名的HTTP请求权限:
<key>NSAppTransportSecurity</key>
<dict>
    <key>NSExceptionDomains</key>
    <dict>
        <key>你的请求域名(例:example.com)</key>
        <dict>
            <key>NSIncludesSubdomains</key>
            <true/>
            <key>NSExceptionAllowsInsecureHTTPLoads</key>
            <true/>
        </dict>
    </dict>
</dict>
  1. 调用接口时,在回调中处理数组赋值和UI刷新逻辑:
override func viewDidLoad() {
    super.viewDidLoad()
    fetchNewsData(forCoutry: "cn", category: "general") { [weak self] newsModel in
        guard let self = self, let model = newsModel else { return }
        // 赋值数组
        self.newsList = model.dataList
        // 刷新对应UI
        self.tableView.reloadData()
    }
}

内容的提问来源于stack exchange,提问作者Resly34

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 20:54:05