CoreDataのデータを更新した際にListViewが更新されない問題について

# アプリ作成環境
* XCode Version 11.3
* SwiftUI

# 背景
SwiftUIのお勉強に、CoreDataを使った簡単なListViewーEditアプリを作ろうと思った。
## 完成イメージ
1. リストにある項目を選んで編集画面に遷移
2. テキストフィールドに表示されている値を変更
3. Saveボタンを押す
4. リストビューに戻り、表示されている文字列が変更されている
![goal-image.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526994/e63fa157-5390-517a-d653-caf4b2cc4352.gif)

# 課題
編集画面で編集してSaveボタンを押してリストビューに戻った時に、文字列の変更が反映されなかった。　　
(CoreData上では変更されているらしく、アプリを再起動すると反映される)

## 問題のあったコード
```swift
import SwiftUI
import CoreData
import Combine

public class Item: NSManagedObject, Identifiable {
    @NSManaged var uuid: UUID
    @NSManaged var name: String
}

struct ContentView: View {
    @Environment(\.managedObjectContext) var managedObjectContext
    @FetchRequest(entity: Item.entity(), sortDescriptors: []) var items: FetchedResults<Item>

    var body: some View {
        NavigationView {
            List {
                ForEach(self.items) { item in
                    NavigationLink(destination: DetailView(item: item)){
                        ItemRowView(item: item)
                    }
                }
            }
        .navigationBarItems(trailing: AddItemButton())
        }
    }
}

struct ItemRowView: View {
    var item: Item
    var body: some View {
        VStack(alignment: .leading) {
            Text(item.name).font(.headline)
        }
    }
}

struct DetailView: View {
    @Environment(\.presentationMode) var presentationMode
    @Environment(\.managedObjectContext) var managedObjectContext

    var item: Item
    
    @State var name: String = ""
    
    var body: some View {
        VStack{
            Group {
                TextField("name", text: self.$name)
                    .textFieldStyle(RoundedBorderTextFieldStyle())
            }.onAppear(perform: {
                self.name = self.item.name
            })
            Button(action: {
                self.item.name = self.name
                do {
                    try self.managedObjectContext.save()
                } catch {
                    print(error)
                }
                self.presentationMode.wrappedValue.dismiss()

            }, label: { Text("Save") })
        }
    }
}

struct AddItemButton: View {
    @Environment(\.managedObjectContext) var managedObjectContext

    var body: some View {
        Button(action: {
            let item = Item(context: self.managedObjectContext)
            item.uuid = UUID()
            item.name = "New Item"
            do {
                try self.managedObjectContext.save()
            } catch {
                print(error)
            }

        }, label: {
            Image(systemName: "plus")
        })
    }
}
```
# 解決方法
## その1
ContentView内のItemRowViewの部分を展開？する。
これで何故動くのか疑問があったがとりあえず動いた。
いろいろやっていく中で、itemのObserveができてないのでは？と予想(言葉の使い方がおかしいかもしれない)。

```swift
struct ContentView: View {
    @Environment(\.managedObjectContext) var managedObjectContext
    @FetchRequest(entity: Item.entity(), sortDescriptors: []) var items: FetchedResults<Item>

    var body: some View {
        NavigationView {
            List {
                ForEach(self.items) { item in
                    NavigationLink(destination: DetailView(item: item)){
                        //ItemRowView(item: item)
                        VStack(alignment: .leading) {
                            Text(item.name).font(.headline)
                        }
                    }
                }
            }
        .navigationBarItems(trailing: AddItemButton())
        }
    }
}
//struct ItemRowView: View {
//    var item: Item
//    var body: some View {
//        VStack(alignment: .leading) {
//            Text(item.name).font(.headline)
//        }
//    }
//}
```
## その2
以下のQAを参考に修正した。こっちの方法のほうがそれっぽい気がする。
スマートなやり方があったら教えていただけると幸いです。
https://stackoverflow.com/questions/58068446/nsmanagedobject-changes-do-not-trigger-objectwillchange

```swift
public class Item: NSManagedObject, Identifiable {
    @NSManaged var uuid: UUID
    @NSManaged var name: String
    
    // willChangeValueをオーバーライド
    override public func willChangeValue(forKey key: String){
        super.willChangeValue(forKey: key)
        self.objectWillChange.send()
    }
}
・・・
struct ItemRowView: View {
    // 引数に@ObservedObjectを付与
    @ObservedObject var item: Item
    var body: some View {
        VStack(alignment: .leading) {
            Text(item.name).font(.headline)
        }
    }
}
```