Устранение взаимосвязи между основными данными и ошибка SIGABRT - PullRequest
1 голос
/ 27 сентября 2019

Я переучиваю основы базовых данных swift с помощью быстрой игровой площадки.

Я пишу основные данные длинной рукой, чтобы написать простое приложение для игровых площадок, где

One Company имеет много Employees

Я постоянно получаю сообщение об ошибке:

ошибка: выполнение было прервано, причина: сигнал SIGABRT.

Когда речь идет о сохранении отношений между компанией и одним сотрудником, но я не уверен, почему их поднимают.

Мой код теперь следующий:

// Swift playground code
import CoreData

class NotificationListener: NSObject {
    @objc func handleDidSaveNotification(_ notification:Notification) {
        print("did save notification received: \(notification)")
    }
}

let listener = NotificationListener()
NotificationCenter.default.addObserver(listener, selector: #selector(NotificationListener.handleDidSaveNotification(_:)), name: NSNotification.Name.NSManagedObjectContextDidSave, object: nil)


// Define managed object
let model = NSManagedObjectModel()

//: [Entities]

let companyEntity = NSEntityDescription()
companyEntity.name = "Company"

let employeeEntity = NSEntityDescription()
employeeEntity.name = "Employee"
employeeEntity.indexes = []

//: [Attributes]

let companyNameAttribute = NSAttributeDescription()
companyNameAttribute.name = "name"
companyNameAttribute.attributeType = NSAttributeType.stringAttributeType
companyNameAttribute.isOptional = false

let countryAttribute = NSAttributeDescription()
countryAttribute.name = "country"
countryAttribute.attributeType = NSAttributeType.stringAttributeType
countryAttribute.isOptional = false

let employeeNameAttribute = NSAttributeDescription()
employeeNameAttribute.name = "name"
employeeNameAttribute.attributeType = NSAttributeType.stringAttributeType
employeeNameAttribute.isOptional = false

let ageAttribute = NSAttributeDescription()
ageAttribute.name = "age"
ageAttribute.attributeType = NSAttributeType.integer16AttributeType
ageAttribute.isOptional = false

// Relationships

let companyRelationship = NSRelationshipDescription()
let employeeRelationship = NSRelationshipDescription()

companyRelationship.name = "company"
companyRelationship.destinationEntity = companyEntity
companyRelationship.minCount = 0
companyRelationship.maxCount = 0
companyRelationship.deleteRule = NSDeleteRule.cascadeDeleteRule
companyRelationship.inverseRelationship = employeeRelationship

employeeRelationship.name = "employees"
employeeRelationship.destinationEntity = employeeEntity
employeeRelationship.minCount = 0
employeeRelationship.maxCount = 1
employeeRelationship.deleteRule = NSDeleteRule.nullifyDeleteRule
employeeRelationship.inverseRelationship = companyRelationship

companyEntity.properties = [companyNameAttribute, countryAttribute, employeeRelationship]
employeeEntity.properties = [employeeNameAttribute, ageAttribute, companyRelationship]

model.entities = [companyEntity, employeeEntity]

// Create persistent store coordinator
let persistentStoreCoordinator = NSPersistentStoreCoordinator(managedObjectModel:model)

do {
    try persistentStoreCoordinator.addPersistentStore(ofType: NSInMemoryStoreType, configurationName: nil, at: nil, options: nil)
} catch {
    print("error creating persistentStoreCoordinator: \(error)")
}

let managedObjectContext = NSManagedObjectContext(concurrencyType: NSManagedObjectContextConcurrencyType.mainQueueConcurrencyType)
managedObjectContext.persistentStoreCoordinator = persistentStoreCoordinator

// Companies
let companyABC = NSEntityDescription.insertNewObject(forEntityName: "Company", into: managedObjectContext)
companyABC.setValue("ABC Ltd", forKeyPath: "name")
companyABC.setValue("United States", forKeyPath: "country")

let companyDelta = NSEntityDescription.insertNewObject(forEntityName: "Company", into: managedObjectContext)
companyDelta.setValue("Delta", forKeyPath: "name")
companyDelta.setValue("Canada", forKeyPath: "country")

let tom = NSEntityDescription.insertNewObject(forEntityName: "Employee", into: managedObjectContext)
tom.setValue("Tom", forKey: "name")
tom.setValue(22, forKey: "age")
tom.setValue(companyABC, forKey: "company") // <<-- Throws error

let sarah = NSEntityDescription.insertNewObject(forEntityName: "Employee", into: managedObjectContext)
sarah.setValue("Sarah", forKey: "name")
sarah.setValue(41, forKey: "age")
sarah.setValue(companyDelta, forKey: "company")   // <<-- Throws error



func save(context: NSManagedObjectContext) {

    // Save context
    do {
        try context.save()
    } catch {
        print("error saving context: \(error)")
    }

    let fetchRequest = NSFetchRequest<NSManagedObject>(entityName: "Company")

    var results: [NSManagedObject] = []

    do {
        results = try managedObjectContext.fetch(fetchRequest)

        print ("\n#\(results.count) records found\n")

    } catch {
        print("error executing fetch request: \(error)")
    }

    print("results: \(results)")
}

save(context: managedObjectContext)

Проблема возникаетпри попытке сохранить одного сотрудника:

let tom = NSEntityDescription.insertNewObject(forEntityName: "Employee", into: managedObjectContext)
tom.setValue("Tom", forKey: "name")
tom.setValue(22, forKey: "age")
tom.setValue(companyABC, forKey: "company")

Ошибка возникает при попытке установить companyABC в качестве отношения для объекта tom.

Цель состоит в том, чтобы сделать Tom и сотрудник companyABC

Я считаю, что отношения были созданы правильно.

Но я не уверен в том, что является причиной ошибки.

Таким образом, мой запрос: Как я могу устранить эту ошибку?

С благодарностью

1 Ответ

1 голос
/ 27 сентября 2019
...
tom.setValue(Set([companyABC]), forKey: "company")
...
sarah.setValue(Set([companyDelta]), forKey: "company")
...

Потому что в этом случае, если вы сгенерируете модель класса с XCode из графика CoreData, он будет генерировать объекты, у которых свойство company равно (NS)Set. Я думаю, что это должно быть написано где-то в документации CoreData, но, к сожалению, set - слишком распространенное слово. Изменить, найти его.

Из doc :

Во всплывающем меню «Назначение» определяется, какой объект (или объекты) возвращается при обращении к связи в коде.Если отношение определено как to-one, возвращается один объект (или nil, если отношение может быть необязательным). Если отношение определено как to-many, возвращается набор (или снова ноль, если отношение может быть необязательным).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...