将逻辑放入 CoreData 模型

Posted

技术标签:

【中文标题】将逻辑放入 CoreData 模型【英文标题】:Putting Logic in a CoreData Model 【发布时间】:2015-12-12 05:04:29 【问题描述】:

我是 ios 开发的新手,正在开发一个语言抽认卡应用程序,在该应用程序中会向用户展示抽认卡,然后用户可以说出他们是否记得它。如果他们点击“是”,则该卡计划在未来某个时间返回,具体取决于各种变量,如果他们点击“否”,则该卡计划很快返回。 (间隔重复系统)

我的问题是,当我使用 CoreData 作为应用程序的存储时,哪里是放置这个调度逻辑的好地方?

我想到的两个地方是:

在抽认卡的 NSManagedObject 的子类中。

例如,我可以这样做:

Flashcard : NSManagedObject 
    ...
    @NSManaged var nextReview: NSDate?
    func reschedule() 
    // logic to assign a new date to nextReview
    
    ...

然后在控制器中,它可以访问 CoreData(模型)和我可以简单地编写的视图:

// When the user has tapped a response:
flashcard.reschedule()

我可以看到这种方法的一个优点是,如果我必须在不同的控制器中分配一个新的日期,我就不必重写调度逻辑。

或:

在控制器中计算新日期,然后更新模型。

FlashcardViewController 
    ...
    // When the user has tapped on a response:
    let newReviewDate = scheduler.calculateNextReviewDate(...)
    flashcard.nextReview = newReviewDate

重新调度逻辑应该是控制器应该负责的事情,还是模型应该做的事情。或者 CoreData NSManagedObject 应该只是具有验证 getter 和 setter 的数据吗?有没有在 iOS 开发中首选的方式?

我想归根结底,我想知道 NSManagedObject 子类是否应该管理自己的逻辑。

作为一个附加但相关的问题,这种类型的事情,决定以哪种方式组织代码对我来说似乎是一个弱点。是否有任何好的资源可供我阅读,以了解更多关于此类决策的信息,更重要的是,了解何时以及为何使用它们是好/坏。

【问题讨论】:

【参考方案1】:

出于您提到的原因,我会将逻辑放入模型中。

但是,我不会将它直接放在 NSManagedObject 的子类中,而是为其创建一个类别,例如FlashCard+Schedule.swift。这样,除了您所说的优点之外,如果您想重新生成模型,所有逻辑仍将存在于单独的文件中。

编辑:这是一个很好的article,它在更高层次上涵盖了这个主题(架构模式)。

【讨论】:

谢谢。那篇文章特别回答了我的很多问题! 欢迎您!如果您觉得有帮助,请采纳答案。干杯! xCode 7 中的新功能,您不需要创建类别(swift 中的扩展),因为 xCode 会为您完成,它只会包含您的属性。你可以把你的逻辑放在你的管理对象中【参考方案2】:

既不是模型也不是控制器。这称为业务逻辑。业务逻辑应该在一个单独的类中,只做这个(单一职责)。我宁愿拥有一个执行业务逻辑的服务类,并将模型保留为简单的存储和控制器,用于将模型格式化为 UI/视图。

【讨论】:

【参考方案3】:

只是作为一个建议,因为我最近用 Swift 编写了这样一个应用程序。

我的解决方案是在每张卡上存储一个记忆分数,每当它被标记为“正确”或“不正确”时更新它(我也允许“无反应”)。

接下来选择哪张卡片的逻辑是在 Dealer 单例中,它可以依靠这些分数来做出有或没有随机元素的好选择。事实上,该算法非常简单,可以很好地成为“交易”视图控制器的一部分。

【讨论】:

以上是关于将逻辑放入 CoreData 模型的主要内容,如果未能解决你的问题,请参考以下文章

从自定义框架访问 Coredata 时应用程序崩溃

CoreData:错误:无法在 NSManagedObject 类“Collect”上调用指定的初始化程序

CoreData 模型架构和关系

使用 NSFetchedResultsController 按日期将 CoreData 模型排列成部分[重复]

Core Data 逻辑分布?

如何理解苹果文档中CoreData的父/子模型?