我在 SwiftUI 視圖模型中使用此代碼:
car.publisher(for: \.sold, options: [.new])
.removeDuplicates()
.receive(on: RunLoop.main)
.sink { [weak self] sold in
guard let self = self else { return }
.... here is reference the car entity for some logic ....
}
.store(in: &subscribers)
一切正常,直到我實際洗掉該 Car 物體并且接收器啟動然后.... here is reference the car entity for some logic ....運行并且它在嘗試使用 DELETED Core Data 物體時崩潰。
我的模式在這里似乎是錯誤的。當從背景關系中洗掉該汽車物體時,該接收器是否有辦法自動取消?
uj5u.com熱心網友回復:
您可以使用faultingState來跟蹤這種情況。從檔案:
0如果物件完全初始化為托管物件并且沒有轉換到另一個狀態或從另一個狀態轉換,否則為其他值。此屬性允許您在接收到鍵值觀察更改通知時確定物件是否處于過渡階段。
所以你可以像這樣忽略這個事件:
.sink { [weak self] sold in
guard let self = self, car.faultingState == 0 else { return }
//
}
如果你想真正取消這個接收器,你可以將可取消物件存盤在物件中,這樣你就可以在prepareForDeletion.
為此,您需要更改目標代碼生成,可以在此處找到更多資訊。更改為Category/Extension - 在這種情況下,您可以創建一個類并覆寫prepareForDeletion,Xcode 仍會為您生成所有屬性。
現在您可以將所有發布者邏輯移動到您的類中:
@objc(Car)
public class Car: NSManagedObject {
private var subscribers = Set<AnyCancellable>()
func observe<Value: Equatable>(keyPath: KeyPath<Item, Value>, receiveValue: @escaping ((Value) -> Void)) {
publisher(for: keyPath, options: [.new])
.removeDuplicates()
.receive(on: RunLoop.main)
.sink(receiveValue: receiveValue)
.store(in: &subscribers)
}
public override func prepareForDeletion() {
super.prepareForDeletion()
subscribers.removeAll()
}
}
或者只是用它來存盤cancellables。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/452940.html
