英文:
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<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)
}
}
}
答案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 > $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 > $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<Season>
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<Season> {
return seasons ?? Set<Season>()
}
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)
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论