Свойство NSManagedObject неправильно задается при инициализации

#ios #swift #xcode #core-data #swiftui

Вопрос:

У меня есть основной объект даты, который я создаю для удобства в одном из моих второстепенных представлений. Эта инициализация запускается при загрузке приложения (чего я не понимаю, так как представление не отображается, но на самом деле проблема не в этом).

Моя проблема в том, что свойство, locations , в моем основном объекте данных возвращается Optional(Set([])) при загрузке приложения. Затем это присваивается Optional(Set([])) свойству @Published в инициализаторе. Затем, когда я позже сравню эти два, @Published = Optional(Set([])) и locations = nil .

 WorkItemViewModel.swift

@Published var locations: Set<Location>?

convenience init(viewContext: NSManagedObjectContext) {
    let childObjectContext = NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType)
    childObjectContext.parent = viewContext
    self.init(workItem: WorkItem(insertIntoManagedObjectContext: childObjectContext), viewContext: viewContext)
}

init(workItem: WorkItem, viewContext: NSManagedObjectContext) {
    self.viewContext = viewContext
    self.workItem = workItem
    self.locations = workItem.locations
}
 

Как вы можете видеть, я создаю объект в дочернем контексте, чтобы он не отображался в других представлениях.

Этот удобный инициализатор создает объект и затем вызывает обычный инициализатор, который загружает @Опубликованные свойства с информацией, относящейся к объекту.

Я также создал удобную инициализацию внутри фактического объекта, который я вызываю, чтобы создать объект и загрузить его со значениями по умолчанию. Вот здесь я ставлю locations на ноль:

 WorkItem CoreDataClass.swift

// wrapper around the actual property to easily set it
var locations: Set<Location>? {
    get { return locationsValue as? Set<Location> }
    set { locationsValue = newValue as NSSet? }
}

convenience init(title: String = "", category: CategoryType = .general, dueDate: Date = Date(), frequency: FrequencyType = .oneTime, locations: Set<Location>? = nil, notes: String = "", insertIntoManagedObjectContext context: NSManagedObjectContext!) {
    let entity = NSEntityDescription.entity( forEntityName: "WorkItem", in: context)!
    self.init(entity: entity, insertInto: context)
    self.title = title
    self.category = category
    self.dueDate = dueDate
    self.frequency = frequency
    self.locations = locations
    self.notes = notes
}
 

Я не совсем понимаю, что здесь происходит. Я знаю, что могу по умолчанию использовать свойство @Published с нулем в модели представления, но я хотел бы сохранить значения по умолчанию в одном месте на объекте.

Я проверил, и свойство фактические местоположения не будет установлено в ноль, пока я не загружу представление.

итак, другими словами:

загрузить приложение -> просмотр запусков инициализации ->> свойство объекта устанавливает @опубликованное свойство в >> Optional(Set([])) -> показать представление ->> свойство объекта установлено в nil

Комментарии:

1. Может быть, один из способов справиться с этим лучше-сделать свойство оболочки необязательным, чтобы вы всегда работали с пустым набором?

Ответ №1:

Я подозреваю, что проблема в том, что вы childObjectContext существуете только в рамках кода инициализации. Как только инициализация завершена, childObjectContext она уничтожается вместе со всей содержащейся в ней информацией об объектах, зарегистрированных в ней. Следовательно, свойства вашего объекта возвращаются к нулю.

Сохраните ссылку на childObjectContext как var в WorkItemViewModel.