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

我有两个实体:

议程活动

议程日期

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

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

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

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

  1. 用户正在创建一个新的 AgendaDate(所以是一个新的上下文)
  2. 用户正在更新现有的 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 感谢您的回答。我将更改属性名称。反向关系已经存在......我将其命名为:议程事件。我编辑了我的问题来解释什么是议程事件..

标签: ios swift core-data nsmanagedobject


【解决方案1】:

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

  1. 您创建或分配dateToAdd
  2. 第一次通过循环开始
    1. dateToAdd 的日期设置为date
    2. dateToAdd 附加到 agendaEvent
    3. 上下文被保存
  3. 下一个循环开始
    1. 日期再次设置在dateToAdd(这会更改副本中已在agendaEvent 中的日期)
    2. agendaEvent 被告知附加它刚刚添加的 same dateToAdd,它忽略了它,因为该实体已经在其 agendaDates 列表中
    3. 上下文被保存,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 不会被覆盖,所以仍然显示......所以我试图让用户插入数组的所有数据并覆盖现有对象...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-19
  • 2020-10-15
  • 1970-01-01
  • 1970-01-01
  • 2011-12-18
相关资源
最近更新 更多