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

CoreData删除实体对象后查询返回nil,如何避免出现空值

已删除对象显示为nil

CoreData查询返回nil问题解答

谓词写法正误说明

你写的"Username!=nil"是错误的,CoreData谓词对属性名大小写敏感,你定义的Users实体属性是小写开头的username,大写开头的Username无法匹配到对应属性,会导致谓词完全失效。正确写法为:
NSPredicate(format: "username != nil")


查询返回nil的核心原因

从你提供的代码来看,删除操作后查询到nil和删除逻辑本身无关,是你的代码存在两处逻辑错误:

  • 删除操作多余插入了空对象:deleteAction中你调用了openDatabse()方法,这个方法内部会向当前上下文插入一个新的空Users对象,该对象没有赋值任何属性,也没有被保存或删除,后续fetch操作会把这个未持久化的空对象一同查询出来,它的所有属性自然都是nil。
  • fetch请求未加有效谓词:你当前的fetchData方法没有给查询请求设置谓词,所有上下文中的Users对象(包括未持久化的空对象、已标记删除还未保存的对象)都会被返回。

修复方案

步骤1:修正删除操作的冗余逻辑

deleteAction和deleteData方法不需要创建新对象,删掉多余的openDatabse调用,修正后代码如下:

@IBAction func deleteAction(_ sender: Any){
    deleteData()
    _ = fetchData()
}

func deleteData(){
    let result = self.fetchData()
    if let data = result.last{
        context.delete(data)
    }
    do {
        try context.save()
    }
    catch{
        print("Error on saving context")
    }
}

步骤2:给fetch请求添加正确谓词

在fetchData方法中为查询请求加上大小写匹配的谓词,也可以选择开启includesPendingChanges = false仅查询已持久化到数据库的记录,忽略上下文未保存的变更:

func fetchData() -> [Users]
{
    var users : [Users] = []
    print("Fetching Data..")
    let request = Users.fetchRequest()
    request.returnsObjectsAsFaults = false
    // 添加正确谓词
    request.predicate = NSPredicate(format: "username != nil")
    // 可选:仅查询已持久化的记录,忽略未保存的变更
    // request.includesPendingChanges = false
    do {
        let result = try context.fetch(request)
        users = result
        for data in result {
            print("Username: ",data.username ?? "nil",", Age : ",data.age ?? "nil")
        }
    } catch {
        print("Fetching data Failed")
    }
    return users
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 23:06:02