专栏首页韦弦的偶尔分享SwiftUI Core Data:创建 NSManagedObject 子类

SwiftUI Core Data:创建 NSManagedObject 子类

NSManagedObject - 韦弦zhy

当我们创建一个新的Core Data实体时,Xcode在构建代码时会自动为我们生成一个托管对象类。然后,我们可以在SwiftUI @FetchRequest中使用它在我们的用户界面中显示数据,但是正如您所看到的那样,这很痛苦:要解包的选项很多,因此您需要编写许多分散使用空合运算符才能​​使代码正常工作。

有两种解决方案:快速简便的解决方案有时会出现问题,或者较慢的解决方案从长远来看会更好。

首先,让我们创建一个要使用的实体:打开数据模型并创建一个名为Movie的实体,其属性为:“title” (string), “director” (string), 和 “year” (integer 16)。在离开数据模型编辑器之前,我希望您转到“View”菜单,然后选择 " Inspectors > Show Data Model Inspector",它会在Xcode的右侧弹出一个窗格,其中包含有关您当前选择的内容的更多信息。

当您选择 Movie 时,您会看到该实体的各种数据模型选项,但是我特别希望您看到一个选项:“Codegen”。这控制了Xcode在我们构建项目时如何将实体生成为托管对象类,默认情况下它将是类定义。我想将其更改为“Manual/None”,这使我们可以完全控制类的生成方式。

Codegen

现在,Xcode不再生成供我们在代码中使用的Movie类,除非实际使用一些实际的Swift代码制作该类,否则我们将无法在代码中使用它。为此,请转到“Editor”菜单,然后选择“Create NSManagedObject Subclass”,确保选择了“CoreDataProject”,然后按Next,然后确保选择了 Movie,然后再次按 Next。系统会询问您Xcode将代码保存在何处,因此请确保选择左侧带有黄色文件夹图标的“CoreDataProject”,然后还要选择CoreDataProject文件夹。准备就绪后,请按创建以完成该过程。

我们只是想让Xcode将其生成的代码转换为我们可以查看和更改的实际Swift文件,尽管请记住,如果更改为我们生成的Xcode文件然后重新生成这些文件,所做的更改将会丢失。

Xcode将为我们生成两个文件,但是我们只关心其中一个:Movie + CoreDataProperties.swift。在其中,您将看到以下三行代码:

@NSManaged public var title: String?
@NSManaged public var director: String?
@NSManaged public var year: Int16

在那小段代码中,您可以看到三件事:

  1. 这就是我们的可选问题的来源。
  2. year不是可选的,这意味着Core Data将为我们采用默认值。
  3. 它在所有三个属性上使用@NSManaged

@NSManaged不是属性包装器——它比SwiftUI中的属性包装器要旧得多。实际上,这揭示了Core Data在内部如何工作的一些信息:它们不是真正存在于类中的作为属性的那些值,而是它们实际上只是在Core Data用于存储其信息的字典中进行读写。当我们读取或写入@NSManaged属性的值时,Core Data会捕获并在内部对其进行处理——与简单的Swift字符串相去甚远。

现在,您可能会查看该代码,并认为“我在那里不希望有可选值”,然后将其更改为:

@NSManaged public var title: String
@NSManaged public var director: String
@NSManaged public var year: Int16

你知道吗?那将绝对有效。您可以使用与以前相同的代码制作Movie对象,使用提取请求查询它们,保存其托管对象上下文,等等,所有这些都没有问题。

但是,您可能会注意到一些奇怪的事情:即使我们的属性不再是可选的,也可以在不提供这些值的情况下创建Movie类的实例。这应该是不可能的:这些属性不是可选的,这意味着它们必须始终具有值,但是我们可以在不使用值的情况下创建它们。

这是@NSManaged魔术中的一小部分的展露——请记住,这些不是真正的属性,因此@NSManaged让我们做不该做的事情。它确实可以正常工作,对于小型的Core Data项目和/或学习者,我认为删除可选项是一个好主意。但是,还有一个更深层次的问题:Core Data 是惰性的。

还记得Swift的 lazy 关键字,以及它如何让我们延迟工作直到真正需要它?除了数据之外,Core Data的功能大致相同:有时看起来有些数据实际上不是已经加载的,因为Core Data试图最大程度地减少其对内存的影响。

我们不需要做任何特殊的工作来处理这些错误,因为一旦我们尝试读取它们,Core Data就会透明地获取真实数据并将其发送回去—— @NSManaged的另一个好处。但是,当我们开始关注Core Data 的属性类型时,就有可能暴露其独特的不足之处。这件事显然无法像Swift所期望的那样起作用,如果我们尝试绕开它,那么我们就会引来很多麻烦——我们的值应该是绝对不会为nil,但却在任何时候都可能突然为nil

相反,您可能需要考虑添加计算属性,以帮助我们安全地访问可选值,同时还允许我们将处理可选值代码全部存储在一个位置。例如,将其添加为Movie的属性可确保我们始终具有有效的标题字符串来使用:

public var wrappedTitle: String {
    title ?? "Unknown Title"
}

这样,整个代码的其余部分就不必担心Core Data的可选值,如果要更改默认值,可以在一个文件中完成。

译自 Creating NSManagedObject subclasses

为什么 ForEach 可以使用 .self ?

Hacking with iOS: SwiftUI Edition

有条件地保存 NSManagedObjectContext

赏我一个赞吧~~~

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Hacking with iOS: SwiftUI Edition - 书虫项目——挑战

    恭喜您完成了另一个SwiftUI项目!借助Core Data等技术,您现在可以构建一些与用户互动的应用,并且,最重要的是,记住他们输入的内容。尽管我们只涉及界面...

    韦弦zhy
  • Hacking with iOS: SwiftUI Edition - Core Data 项目——引言

    该技术项目将更详细地研究Core Data,首先是对一些基本技术的总结,然后逐步解决一些更复杂的问题。

    韦弦zhy
  • 100 Days of SwiftUI —— Day 54:书虫(二)

    今天,我们将开始应用您学到的新技术来构建我们的应用程序,使用Core Data来创建图书,并使用通过@Binding构建的自定义的RatingView组件来让用...

    韦弦zhy
  • 【Hello NLP】CS224n笔记[7]:机器翻译和seq2seq

    相比于计算机视觉,NLP可能看起来没有那么有趣,这里没有酷炫的图像识别、AI作画、自动驾驶,我们要面对的,几乎都是枯燥的文本、语言、文字。但是,对于人工智能的征...

    beyondGuo
  • Facebook宣布机器翻译全面采用神经网络,现每日处理45亿次翻译

    【新智元导读】Facebook 今天宣布,从使用基于短语的机器翻译模型改为使用神经网络系统来处理其社交网络后端每天的翻译请求,每天翻译超过 45 亿次。与基于短...

    新智元
  • 如何为机器学习设置Python环境

    为Python设置机器学习环境可能是一项棘手的任务。如果你之前从未设置过类似的东西,那么可能需要花费数小时来处理不同的命令。

    AiTechYun
  • 混合线性模型如何进行多重比较

    这里,得到的LSD = 6.708889, 多重比较中,用水平的平均值的差值,与LSD比较,如果大于LSD,则认为两水平达到显著性差异。

    邓飞
  • AutoML:自动设计自动驾驶机器学习模型

    在Waymo,机器学习几乎在我们自动驾驶系统的每个模块都起着关键作用。它可以帮助我们的汽车看清周围的环境、感知世界、预测其他人的行为,并决定自己下一步最佳移动。

    陆道峰
  • 使用OpenCV实现哈哈镜效果

    有趣的镜子不是平面镜子,而是凸/凹反射表面的组合,它们会产生扭曲效果,当我们在这些镜子前面移动时,这些效果看起来很有趣。

    小白学视觉
  • [脑书笔记]《你为什么而工作》:请尊重你自己

    核心内容:我们为什么要工作?我们为什么要放弃既快乐又刺激的安逸生活,每天早晨睡眼惺忪地从舒适的床上挣扎而起?多么愚蠢的问题啊。我们工作当然是因为我们要养家糊口。...

    rocket

扫码关注云+社区

领取腾讯云代金券