英文:
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
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
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
如果Show
是手动创建的,无论如何,请将集合声明为非可选的Set
,删除问号并取消模型中的"Optional"选项
@NSManaged public var seasons : Set
And actually you don't need the conversion to Array
. The set can be enumerated like an array.
实际上,你不需要将其转换为Array
。你可以像处理数组一样处理这个集合。
If you really need an optional add a computed property which unwraps the optional safely
如果你确实需要一个可选值,可以添加一个计算属性,安全地取消可选值
var unwrappedSeasons : Set
return seasons ?? Set
}
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)
}
}
英文:
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)
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论