简体   繁体   English

CurrentValueSubject 的属性包装器 - memory 管理

[英]Property Wrapper for CurrentValueSubject - memory management

I would like to create a property wrapper for CurrentValueSubject .我想为CurrentValueSubject创建一个property wrapper I have done this like that:我这样做是这样的:

@propertyWrapper
public class CurrentValue<Value> {

    public var wrappedValue: Value {
        get { projectedValue.value }
        set { projectedValue.value = newValue }
    }

    public var projectedValue: CurrentValueSubject<Value, Never>

    public init(wrappedValue: Value) {
        self.projectedValue = CurrentValueSubject(wrappedValue)
    }

}

This works but there is a little thing I would like to change with it - use struct instead of class. The problem with using struct for this is that sometimes I could get Simultaneous accesses error.这行得通,但有一点我想用它来改变——使用 struct 而不是 class。为此使用 struct 的问题是有时我可能会遇到Simultaneous accesses错误。 And I know why, this happens when in sink from this publisher I would try to read the value from wrapped value.我知道为什么,当sink从这个发布者接收到我试图从包装值中读取值时,就会发生这种情况。 So for example with code like this:因此,例如使用这样的代码:

@CurrentValue
let test = 1
$test.sink { _ in
    print(self.test)
} 

And I more or less know why - because when projectedValue executes its observation, wrapped value is still in process of setting its value.而且我或多或少知道为什么 - 因为当projectedValue执行其观察时,包装值仍在设置其值的过程中。 In class this is ok, because it would just change the value, but with struct it actually modifies the struct itself, so Im trying to write and read from it at the same time.在 class 中,这没问题,因为它只会更改值,但对于结构,它实际上修改了结构本身,所以我试图同时写入和读取它。

My question is - is there some clever way to overcome this, while still using struct?我的问题是 - 是否有一些巧妙的方法来克服这个问题,同时仍然使用结构? I don't want to dispatch async .我不想dispatch async

Also I know that @Projected works similarly to this propertyWrapper , but there is a big difference - Projected executes on willSet , while CurrentValueSubject on didSet .我也知道@Projected的工作方式与此propertyWrapper类似,但有很大的不同 - ProjectedwillSet上执行,而CurrentValueSubjectdidSet上执行。 And Projected has the same issue anyway.无论如何, Projected也有同样的问题。

I know that I can read the value inside the closure, but sometimes Im using this with various function calls, that might eventually use self.test instead.我知道我可以读取闭包内的值,但有时我会在各种 function 调用中使用它,最终可能会改用self.test

Try my implementation试试我的实现

@propertyWrapper
class PublishedSubject<T> {
    
    var wrappedValue: T {
        didSet {
            subject.send(wrappedValue)
        }
    }
    
    var projectedValue: some Publisher<T, Never> {
        subject
    }
    
    private lazy var subject = CurrentValueSubject<T, Never>(wrappedValue)
    
    init(wrappedValue: T) {
        self.wrappedValue = wrappedValue
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM