- Publisher
import Combine
class SomeObject {
var vsalue: String = "" {
didSet {
print(vsalue)
}
}
var asdfasdf: String = "" {
didSet {
print(asdfasdf)
}
}
}
let someObject = SomeObject()
let publisher = ["울릉도", "동남쪽", "뱃길 따라 이백리"].publisher
_ = publisher.assign(to: \SomeObject.asdfasdf, on: someObject)
//위 아래 두 개 다 같은거
_ = publisher.assign(to: \.asdfasdf, on: someObject)
근데 publisher는 애초에 정해진 값만 가지고 하는거고 값 나중에 외부에서 값 추가가 안됨
ex) 변화가 없는 페이지의 경우 불러온 뒤 publisher를 만들어 그걸 표시하면 되지만 페이지 네이션에 따라 배열이 추가되는 경우라면 사용 못합
- Subject(PassthroughSubject)
import Combine
enum TestError: Error {
case 실패입니다
}
let subject = PassthroughSubject<String, TestError>()
subject.send("zero")
let a = subject.sink(receiveCompletion: { completion in
switch completion {
case .finished:
print("끝~")
case .failure(let error):
print("\(error)")
}
}, receiveValue: { value in
print(value)
})
subject.send("one")
subject.send("two")
subject.send("three")
subject.send(completion: .failure(TestError.실패입니다))
PassthroughSubject 를 이용하면 구독 이후 send를 통해 새로운 값을 추가했을 때 그 값도 반영이 됨
하지만 구독 전에 추가된 값은 반영이 안됨
(추가로 .failure를 send로 전달 할 수도 있으며 아래 보면 .finished로 끝낼 수도 있음)
빨간 부분처럼 조건을 걸어 cancel도 가능하며 cancel되면 그 이후 send는 반영 x
또 finished 혹은 failure가 전달되면 그 이후에 어떤 값이 전달돼도 반영 x
- Subject(CurrentValueSubject)
import Combine
enum TestError: Error {
case 실패입니다
}
let subject = CurrentValueSubject<String, TestError>("울릉도")
let a = subject.sink(receiveCompletion: { completion in
switch completion {
case .finished:
print("끝~")
case .failure(let error):
print("\(error)")
}
}, receiveValue: { value in
print(value)
})
subject.send("동남쪽")
subject.send("뱃길따라 이백리")
subject.send("외로운")
subject.send("섬하나")
"울릉도" 라는 초기값이 할당되어 있고 그 이후로 send되는 값들도 다 반영된다
(나머지 .failure, .finishied, .cancel등 동일)
- Subject와 RxSwift 비교
아는게 RxSwift밖에 없어서 내가 이해하기 편하고자 굳이굳이 비교를 해보자면
'PassthroughSubject'는 rx의 publishSubject, (초기값이 없다)
'CurrentValueSubject'는 rx의 behaviorSubject와 비슷하다고 보여진다 (초기값이 있다
- store 와AnyCancellable
Combine에도 RxSwift의 Disposed(by:) 그리고 DisposeBag과 비슷한 역할을 하는게 있는데
그것이 말고 .store(& )와 Set<AnyCancellable>()이다
사용방법도 거의 동일 ㄷㄷ;;
import Combine
enum TestError: Error {
case 실패입니다
}
//요기다 만들고
var cancellables = Set<AnyCancellable>()
let subject = CurrentValueSubject<String, TestError>("울릉도")
let a = subject.sink(receiveCompletion: { completion in
switch completion {
case .finished:
print("끝~")
case .failure(let error):
print("\(error)")
}
}, receiveValue: { value in
print(value)
}).store(in: &cancellables) //요기서 추가
이런 식으로 말이다
거진 1년을 미뤄왔던 Combine공부...
뭔가 Rx를 처음 공불 할 때 혼란스러워 했던 경험을 몸이 기억해서인지 자꾸 꺼려졌는데 Rx를 이미 알고 있는 입장에서 이렇게 기본 사용법 까지는 금방 했던 것 같다
(속내를 완전히 이해 한다기 보다는 Rx와 비교하면서 공부를 하다 보니 말이다)
이 정도면 그냥 스트림 만들기에는 적당한 것 같고 다음에는 operator에 대해 공부해보려고 한다
'Swift > All' 카테고리의 다른 글
class의 배열만들기(약한 참조 하는 배열, weak array) (0) | 2024.03.25 |
---|---|
xcode 여러개 사용하는 방법(xcodes) (0) | 2023.12.27 |
mac Sonoma에서 xcode 14버전 대 실행시키는 법 (0) | 2023.12.25 |
Github Action을 이용한 CI-CD (트러블 슈팅들...까지) (2) | 2023.12.22 |