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

Swift项目Core Data存储数据失败,收藏页无法展示存储内容问题求助

问题排查与修复方案

你代码中存在多个逻辑错误导致Core Data存储和展示失效,具体问题和修复方案如下:

核心问题列表

  • 保存时未绑定对应cell的数据:点击cell按钮拿到行号后,没有取出当前行对应的Article数据,原来的全局存储变量newsTitle/newsAuthor等始终为nil,导致保存的都是空数据
  • isSaved全局逻辑错误:该变量仅在页面加载时判断是否有过存储记录,只要有过任意存储就永久为true,后续点击所有cell的保存按钮都会直接跳过保存逻辑
  • 收藏页漏设tableView数据源:FavouriteNewsViewController中两次设置了delegate,漏了dataSource赋值,就算有数据也不会渲染列表
  • 页面加载时错误执行空保存:viewDidLoad中直接调用了saveNews(),此时所有数据变量都是nil,会生成无效的空存储记录
  • 收藏页加载数据后未刷新UI:loadSavedNews拿到存储数据后没有调用列表刷新方法,UI不会更新
  • 缺描述字段存储逻辑:Core Data模型的desc字段没有对应Article的description属性赋值,保存后该字段为空

修复代码

1. 替换ViewController中的点击保存逻辑,删除无效全局变量

你可以直接删掉原代码中全局的newsTitle/newsAuthor/urlString/newsDate/isSaved变量,同时删除viewDidLoad中的saveNews()调用,替换didTapCellButton方法如下:

@objc func didTapCellButton(sender: UIButton) {
    let index = sender.tag
    // 校验行号有效性
    guard articles.indices.contains(index) else { return }
    let targetArticle = articles[index]
    
    // 配置查询请求,用新闻url作为唯一标识判断是否已保存,避免重复存储
    let fetchRequest: NSFetchRequest<SavedNews> = SavedNews.fetchRequest()
    fetchRequest.predicate = NSPredicate(format: "url == %@", targetArticle.url ?? "")
    
    do {
        let existItems = try context.fetch(fetchRequest)
        // 仅未保存过的新闻才执行存储
        if existItems.isEmpty {
            let savedNews = SavedNews(context: context)
            savedNews.title = targetArticle.title
            savedNews.author = targetArticle.author ?? "未知作者"
            savedNews.publishedAt = targetArticle.publishedAt
            savedNews.url = targetArticle.url
            savedNews.desc = targetArticle.description ?? "暂无描述"
            // 持久化存储
            try context.save()
            print("新闻保存成功")
        } else {
            print("该新闻已在收藏列表中")
        }
    } catch {
        print("存储操作失败:\(error.localizedDescription)")
    }
}

2. 修复FavouriteNewsViewController的代理设置与数据刷新逻辑

修改viewDidLoad中的代理配置:

override func viewDidLoad() {
    super.viewDidLoad()
    // 修正代理设置,补上dataSource
    favTableView.delegate = self
    favTableView.dataSource = self
    favTableView.register(UINib(nibName: S.FavouriteCell.favouriteCell, bundle: nil), forCellReuseIdentifier: S.FavouriteCell.favouriteCellIdentifier)
    loadSavedNews()
}

修改loadSavedNews方法,加载完数据后刷新列表:

func loadSavedNews() {
    let request: NSFetchRequest<SavedNews> = SavedNews.fetchRequest()
    do {
        savedNews = try context.fetch(request)
        // 主线程刷新UI
        DispatchQueue.main.async {
            self.favTableView.reloadData()
        }
    } catch {
        print("加载收藏数据失败:\(error.localizedDescription)")
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 04:54:01