Swift Combine:删除核心数据实体后调用 sink()
Swift Combine: sink() called after core data entity deletion
我在 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 实体时崩溃。
我的模式在这里似乎是错误的。当那个汽车实体从上下文中删除时,有没有办法让那个接收器自动取消?
您可以使用 faultingState
来跟踪此场景。来自 documentation:
0
if the object is fully initialized as a managed object and not transitioning to or from another state, otherwise some other value. This property allows you to determine if an object is in a transitional phase when receiving a key-value observing change notification.
所以你可以像这样忽略这个事件:
.sink { [weak self] sold in
guard let self = self, car.faultingState == 0 else { return }
//
}
如果你真的想取消这个接收器,你可以在对象中存储可取消的,这样你就可以在 prepareForDeletion
期间取消它们。
为此,您需要更改目标代码生成,可以找到更多信息 here。更改为 Category/Extension - 在这种情况下,您可以创建一个 class 并覆盖 prepareForDeletion
,并且 Xcode 仍会生成所有属性给你。
现在您可以将所有发布者逻辑移至您的 class:
@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()
}
}
或者只是用它来存储可取消项。
我在 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 实体时崩溃。
我的模式在这里似乎是错误的。当那个汽车实体从上下文中删除时,有没有办法让那个接收器自动取消?
您可以使用 faultingState
来跟踪此场景。来自 documentation:
0
if the object is fully initialized as a managed object and not transitioning to or from another state, otherwise some other value. This property allows you to determine if an object is in a transitional phase when receiving a key-value observing change notification.
所以你可以像这样忽略这个事件:
.sink { [weak self] sold in
guard let self = self, car.faultingState == 0 else { return }
//
}
如果你真的想取消这个接收器,你可以在对象中存储可取消的,这样你就可以在 prepareForDeletion
期间取消它们。
为此,您需要更改目标代码生成,可以找到更多信息 here。更改为 Category/Extension - 在这种情况下,您可以创建一个 class 并覆盖 prepareForDeletion
,并且 Xcode 仍会生成所有属性给你。
现在您可以将所有发布者逻辑移至您的 class:
@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()
}
}
或者只是用它来存储可取消项。