App crashes on CoreData deletion…how to code this correctly?

huangapple go评论52阅读模式
英文:

App crashes on CoreData deletion...how to code this correctly?

问题

I have 2 core data entity's set up with a many to one and one to many relationship between them (Show -> Season one to many / Season -> Show many to one). I have the class for Show manually created with the code below. However, when I delete a show or season (if only one), it is crashing the app saying 'Fatal error: Unexpectedly found nil while unwrapping an Optional value' for the following code in the manual class, which was set up to create the relationship between the two entities. I have the app set up to use a for loop to delete all seasons of a show prior to deleting the show as well, which causes the same error, obviously because there are no seasons left. How do I fix this so that it deletes all seasons without an error?

Shows+CoreDataProperties.swift (manual class for Show Entity)

@NSManaged public var season: Set<Seasons>?

public var seasons: [Seasons] {
    let setOfSeasons = season
    return setOfSeasons!.sorted {
        $0.id > $1.id
    }
}

Deletion code within view

// DELETE SHOW
public func deleteShow(show: Shows) {
    deleteSeasonsInShow(show: show)
    viewContext.delete(show)
    do {
        try viewContext.save()
    } catch {
        print(error)
    }
}

// DELETE SEASONS WITHIN SHOW PRIOR TO DELETING SHOW
public func deleteSeasonsInShow(show: Shows) {
    for season in show.seasons {
        viewContext.delete(season)
        do {
            try viewContext.save()
        } catch {
            print(error)
        }
    }
}
英文:

I have 2 core data entity's set up with a many to one and one to many relationship between them (Show -> Season one to many / Season -> Show many to one). I have the class for Show manually created with the code below. However, when I delete a show or season (if only one), it is crashing the app saying 'Fatal error: Unexpectedly found nil while unwrapping an Optional value' for the following code in the manual class, which was setup to create the relationship between the two entities. I have the app set up to use a for loop to delete all seasons of a show prior to deleting the show as well, which causes the same error obviously because there are no seasons left. How do I fix this so that it deletes all seasons without an error?

**Shows+CoreDataProperties.swift (manual class for Show Entity)
**

@NSManaged public var season: Set&lt;Seasons&gt;?

    public var seasons: [Seasons]{
            let setOfSeasons = season
            return setOfSeasons!.sorted{
                $0.id &gt; $1.id
            }
        }

Deletion code within view

    // DELETE SHOW
    public func deleteShow(show: Shows){
        deleteSeasonsinShow(show: show)
        viewContext.delete(show)
        do{
            try viewContext.save()
        } catch{
            print(error)
        }
    }
    
    // DELETE SEASONS WITHIN SHOW PRIOR TO DELETING SHOW
    public func deleteSeasonsinShow(show: Shows){
        
        for season in show.seasons {
            viewContext.delete(season)
            do{
                try viewContext.save()
            } catch{
                print(error)
            }
        }
    }

答案1

得分: 0

Use a guard statement in the computed property to avoid having to use forced unwrapping

public var seasons: [Seasons] {
    guard let season else { return [] }
    return season.sorted {
        $0.id &gt; $1.id
    }
}
英文:

Use a guard statement in the computed property to avoid having to use forced unwrapping

public var seasons: [Seasons] {
    guard let season else { return [] }
    return season.sorted {
        $0.id &gt; $1.id
    }
}

答案2

得分: 0

首先,关于单数/复数方面,你的命名方式令人困惑。实体应以单数形式命名,而一对多的关系应以复数形式命名。

如果 Show 是手动创建的,无论如何都应该将 set 声明为非可选的 Set,通过移除问号并取消模型中的 Optional 复选框。

@NSManaged public var seasons: Set<Season>

实际上,你不需要转换为 Array。该 set 可以像数组一样被枚举。

如果确实需要一个可选项,请添加一个计算属性,安全地取消包装该可选项:

var unwrappedSeasons: Set<Season> {
    return seasons ?? Set<Season>()
}

而且 - 与此无关 - 不要在循环中多次保存上下文。在循环之后调用一次即可。

public func deleteSeasonsInShow(show: Shows) {
    
    for season in show.seasons {
        viewContext.delete(season)
    }
    do {
        try viewContext.save()
    } catch {
        print(error)
    }
}
英文:

First of all your naming is confusing with regard to singular/plural. Entities are supposed to be named in singular form and a to-many relationship is supposed to be named in plural form.

If Show is created manually anyway, declare the set as non-optional Set by removing the question mark and unchecking Optional in the model

@NSManaged public var seasons : Set&lt;Season&gt;

And actually you don't need the conversion to Array. The set can be enumerated like an array.

If you really need an optional add a computed property which unwraps the optional safely

var unwrappedSeasons : Set&lt;Season&gt; {
    return seasons ?? Set&lt;Season&gt;()
}

And - unrelated - do not save the context multiple times in a loop. Call it once after the loop.

public func deleteSeasonsinShow(show: Shows){
    
    for season in show.seasons {
        viewContext.delete(season)
    }
    do {
        try viewContext.save()
    } catch{
        print(error)
    }
}

huangapple
  • 本文由 发表于 2023年3月21日 01:48:08
  • 转载请务必保留本文链接:https://go.coder-hub.com/75793634.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定