iOS 16 中 CoreData 托管对象发生变化但其衍生 (Derived) 属性在 SwiftUI 中不刷新的解决

Posted 大熊猫侯佩

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了iOS 16 中 CoreData 托管对象发生变化但其衍生 (Derived) 属性在 SwiftUI 中不刷新的解决相关的知识,希望对你有一定的参考价值。


引子

今天偶然发现 ios 16 SwiftUI 开发中的一个问题。

具体情景为:

一个 SwiftUI + CoreData 的项目,使用 Xcode 14正式版开发。CoreData 数据库的 FireballGroup 托管对象有一个 derived 属性。


不知道 derived 属性为何物的小伙伴,请参考下面一篇博文:

CoreData如何实现托管对象的“计算”属性字段


在该托管对象内容发生改变时,该 derived 属性应该被重新计算,从而 SwiftUI 界面可以显示计算后的内容。

但测试发现在 iOS 16(无论是真机还是模拟器)中,托管对象被更改不会导致其 derived 属性被重新计算,只有重启 App 后才可以。

同样的代码在 iOS 15 中一切正常!

疑似 iOS 16 的Bug?

很难说这个问题不是一个Bug,因为从道理来说 derived 属性应该被实时刷新。

保不齐在 iOS 16 后续更新中它会被修复。

目前来说,我们可以使用托管对象的 willSave() 方法来临时解决它:

public override func willSave() 
  super.willSave()
  
  let count = fireballs?.count ?? 0
  setPrimitiveValue(count, forKey: #keyPath(FireballGroup.ballCount))

其中 FireballGroup.ballCount 是 FireballGroup 托管对象中的一个普通属性(非derived 属性),我们在 FireballGroup 托管对象发生变化时,实时重新计算 ballCount 的值。

用这种方法,托管对象 derived 属性不刷新的问题得到了临时的解决。

总结

在本篇博文中,我们解决了 iOS 16 Coredata 数据库中托管对象 derived 属性在 SwiftUI 中不刷新(重新计算)的问题,希望可以帮助到大家。

感谢观赏,再会!😎

以上是关于iOS 16 中 CoreData 托管对象发生变化但其衍生 (Derived) 属性在 SwiftUI 中不刷新的解决的主要内容,如果未能解决你的问题,请参考以下文章

iOS:核心数据:如何在托管对象中保留一组有序的对象

在 iOS 项目中管理 coredata/sqlite 数据库生命周期

如何在关系变空时删除托管对象

CoreData如何实现托管对象的“计算”属性字段

iOS CoreData+MoGenerator:如何仅在使用嵌套上下文时初始化托管对象一次?

具有核心数据托管对象的 URL 方案 (iOS)