CoreData删除实体对象后查询返回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
相关产品推荐
相关产品推荐

