Swift - 使用 for 循环将数据添加到核心数据

Posted

技术标签:

【中文标题】Swift - 使用 for 循环将数据添加到核心数据【英文标题】:Swift - adding Data to core data with a for loop 【发布时间】:2017-09-25 17:05:25 【问题描述】:

我有两个实体:

议程活动

议程日期

AgendaEvent 与 AgendaDate 有一对多的关系(关系名称 是议程日期)。

议程日期只有一个属性(日期类型的议程日期)。

我正在尝试将数组的所有值保存到 Agendadate 中。

这种节省可能以两种不同的方式发生。

    用户正在创建一个新的 AgendaDate(所以是一个新的上下文) 用户正在更新现有的 AgendaDate

这是我的代码:

var agendaDateToEdit: AgendaDate // this value is passed through a segue if the user clicked to modify an existing one.
var dateToAdd: AgendaDate!
if agendaDateToEdit == nil 
            dateToAdd = AgendaDate(context: context)
         else 
            dateToAdd = agendaDateToEdit
        

现在我执行 for 循环以从数组中插入项目:

let agendaEvent: AgendaEvent!

if agendaEventToEdit != nil 
  agendaEvent = agendaEventToEdit
 else 
  agendaEvent = AgendaEvent(context:context)


for date in dates 
    dateToAdd.agendaDates = date
    agendaEvent.addToAgendaDates(dateToAdd)
    ad.saveContext()
 

但是以这种方式我只存储数组的最后一个值。

我是 swift 新手,我真的不明白错误在哪里。 如果有人可以提供帮助,我将不胜感激。

谢谢!

【问题讨论】:

首先让我们做一点清理工作。 AgendaDate 理想情况下应该有其现有属性,agendaDates 重命名为 date。这是因为属性是单数而不是复数,并且对于实体及其属性之一使用相同的名称可能会变得非常混乱。接下来考虑添加一个从AgendaDate 回到AgendaEvent 的反对一关系,这样你就可以得到一个日期并弄清楚当时正在发生什么。这些更改将使其他人更容易跟踪您的代码中发生的事情,这有望带来更好的答案。 @theMikeSwan 感谢您的回答。我将更改属性名称。反向关系已经存在......我将其命名为:议程事件。我编辑了我的问题来解释什么是议程事件.. 【参考方案1】:

dateToAdd 定义在for 循环的范围之上,因此它在循环的每次迭代中都存在……

    您创建或分配dateToAdd 第一次通过循环开始
      dateToAdd 的日期设置为date dateToAdd 附加到 agendaEvent 上下文被保存
    下一个循环开始
      日期再次设置在dateToAdd(这会更改副本中已在agendaEvent 中的日期) agendaEvent 被告知附加它刚刚添加的 same dateToAdd,它忽略了它,因为该实体已经在其 agendaDates 列表中 上下文被保存,for 循环继续,直到日期用完。

Core Data 中的多对多关系使用NSSet 存储,这确保每个项目只存在一次。这就是为什么您只会在活动中添加一个AgendaDate

由于您持有一个 AgendaDate 实例并不断更改其日期,因此您会看到日期数组中的最后一个日期是什么。如果在循环中添加断点,您应该会看到AgendaEvents 中的AgendaDate 依次获取每个日期。

如果您每次通过循环创建一个新的dateToAdd,我预计您会看到更好的结果

for date in dates 
    let dateToAdd = AgendaDate(context: context)
    dateToAdd.agendaDates = date
    agendaEvent.addToAgendaDates(dateToAdd)
    ad.saveContext()

【讨论】:

感谢您的回答!最初我按照您的建议完成了它......并且工作完美......它每次都会创建一个新的上下文并存储值......我试图拥有一个包含所有值的唯一上下文,如果它更新它已经存在...但可能是由于我对核心数据知之甚少,我试图做一些没有多大意义的事情... 您应该有一个用于创建所有实体的静态上下文。 假设这一切都在一个类中完成,该类应该有一个属性来保存托管对象上下文。上下文应该由之前的任何内容分配给它,或者应该从应用程序委托中提取上下文。然后您可以使用该属性来创建所有实体。 我相信我会... 如果我每次都创建一个新的上下文它不会工作......那是因为用户可以更改日期......例如他第一次插入 23/09 -24/09 - 25/09,第二次插入 24/09 - 25/09 ...... 23/09 不会被覆盖,所以仍然显示......所以我试图让用户插入数组的所有数据并覆盖现有对象...

以上是关于Swift - 使用 for 循环将数据添加到核心数据的主要内容,如果未能解决你的问题,请参考以下文章

如何在swift中使用for循环将按钮添加到stackview?

如何在后台线程swift中运行for循环

将模块名称添加到核心数据实体

将核心数据添加到现有的选项卡式应用程序(ios swift、Xcode6)

Swift学习笔记之---for循环与while循环

Swift学习笔记之---for循环与while循环