CurrentValueSubject vs @Published
Closed this issue · 0 comments
Daltonicc commented
CurrentValueSubject vs @ Published Property Wrapper
- Combine을 학습하다보면 @ Published라고 하는 프로퍼티래퍼와 CurrentValueSubject라는 개념이 존재한다. @ Published 프로퍼티 래퍼에 감싸진 변수와 CurrentValueSubject 둘다 초기값을 가지고 있고 구독 즉시 초기값을 방출한다는 공통된 특징을 가지고 있다.
@Published var navigationTitleWithPublished: String = "Search"
var navigationTitleWithSubject: CurrentValueSubject<String, Never> = .init("Search")
사실 둘다 공통된 특성을 가지고 있어서 특별히 커스텀 에러 처리를 해줄 필요가 없다면 뭘 사용할지는 취향이다. 다만 몇 가지 부분에 있어서 차이점이 존재한다.
@ Published
- 프로퍼티 래퍼다보니 프로토콜에 선언해줄 수 없다.
protocol SearchViewModelOutput: AnyObject {
func showErrorToast(errorMessage: String)
@Published var error: String { get } // "property 'error' declared inside a protocol cannot have a wrapper"
}
- 마찬가지로 구조체에서도 사용할 수 없다.
struct PublishedTest {
@Published var test: String = "Test" // " 'wrappedValue' is unavailable: @Published is only available on properties of classes"
}
- CurrentValueSubejct와 달리 Combine을 import하지 않아도 사용할 수 있다.
- 해당 프로퍼티 래퍼에 감싸진 변수를 사용할 때는 변수 앞에 기호 '$'를 붙여서 사용해야 한다.
$navigationTitleWithPublished
.sink(receiveValue: { [weak self] title in
self?.navigationItem.title = title
})
.store(in: &cancellables)
- CurrentValueSubejct와 달리 현재 value를 가져오거나 새로운 값을 할당할 때, 따로 프로퍼티를 통하지 않고 바로 접근이 가능하다.
- 마지막으로 이건 사소한거긴 한데, 프로퍼티 래퍼가 앞에 붙음으로써, 상대적으로 코드가 좀 더 깔끔해 보인다는 특징이 있다.
CurrentValueSubject
- 위에서 기술해놓은 @ Published 프로퍼티 래퍼의 특징을 모두 반대로 가지고 있다.
- 프로토콜에 선언해줄 수 있다.
- 구조체에도 사용할 수 있다.
- 반드시 Combine을 import해야 사용가능하다.
- 사용할 때 따로 기호를 붙여줄 필요없다.
- 현재 value를 가져올 때는 value 프로퍼티를 활용해야하고, 새로운 값을 할당할 때는 send메서드를 이용해야한다.
// 현재 value 가져오기
var testCurrnetValueSubject: CurrentValueSubject<String, Never> = .init("Test")
print(testCurrnetValueSubject.value) // "Test"
// 새로운 값 할당하기
testCurrnetValueSubject.send("Test2")
print(testCurrnetValueSubject.value) // "Test2"