티스토리 뷰
안녕하세요. 밀쿄입니다.
오늘은 콤바인에서 연산자들 중에 어떤게 있는 지 알아보겠습니다.
먼저 collect() 입니다.
다음과 같은 Stream이 있습니다.
[1, 2, 3, 4, 5].publisher
.sink(receiveCompletion: { print($0)},
receiveValue: { print($0 )})
.store(in: &cancellable)
//결과
1
2
3
4
5
finished
이 스트림에 collect을 사용해보겠습니다.
[1, 2, 3, 4, 5].publisher
.collect()
.sink(receiveCompletion: { print($0)},
receiveValue: { print($0 )})
.store(in: &cancellable)
//결과
[1, 2, 3, 4, 5]
finished
collection은 버퍼에 개별값을 가지고 있다가 upsteam publisher가 완료되면 downstram에 array형태로 방출해주는 연산자 입니다.
단 이렇게 사용할 때는 갯수제한없이 사용하게 될때는 upsteam에서 방출되는 값을 저장하기 위해 무한량의 메모리를 사용하므로 주의하셔야합니다. 그렇다는건 갯수을 제한해서도 사용할 수 있겠죠?
[1, 2, 3, 4, 5].publisher
.collect(3)
.sink(receiveCompletion: { print($0)},
receiveValue: { print($0 )})
.store(in: &cancellable)
//결과
[1, 2, 3]
[4, 5]
finished
마지막은 버퍼가 가득 차기도 전에 upsteam publisher가 완료되어서 단 2개만 출력이 되었습니다.
이렇듯 갯수를 지정했지만 그 갯수를 채우기전에 upsteam publisher가 완료 되어도 버퍼가 있던 값을 array형태로 방출해줍니다.
두 번째는 map입니다.
upsteam publisher에서 방출한 값을 특정값으로 바꿔주는 역할을 합니다.
[1, 2, 3, 4, 5].publisher
.map({ $0 + 1})
.sink(receiveCompletion: { print($0)},
receiveValue: { print( $0 )})
.store(in: &cancellable)
//결과
2
3
4
5
6
이것 외에도 map에는 keyPath를 사용할 수가 있습니다.
먼저 다음과 같은 Publisher를 봅시다.
struct Person {
var name: String
var age: Int
}
let perosons = [Person(name: "Nick", age: 21)]
perosons.publisher
.sink(receiveCompletion: { print($0)},
receiveValue: { print($0 )})
.store(in: &cancellable)
//결과
Person(name: "Nick", age: 21)
finished
이렇게 나오지만 map을 사용하면 다음과 같이 사용할 수 있습니다.
perosons.publisher
.map(\.name,\.age)
.sink(receiveCompletion: { print($0)},
receiveValue: { print( $0 )})
.store(in: &cancellable)
//결과
("Nick", 21)
finished
그 다음은 replaceNil입니다.
[1, 2, 3, 4, 5, nil].publisher
.replaceNil(with: 0)
.compactMap({ $0 })
.sink(receiveCompletion: { print($0)},
receiveValue: { print( $0 )})
.store(in: &cancellable)
//결과
1
2
3
4
5
0
간단하게 nil일 경우 지정한 값으로 변환해주는 연산자 입니다.
사실 위에서 compactMap이 없었다면 출력 값은 Optional( )이런 형태로 나옵니다,
즉, 옵셔녈값을 옵셔널 아닌값으로 만들어주는 것이 아니라 nil이 아니라 다른값으로 변환해주는 연산자라는게 핵심입니다.
그 다음은 scan 입니다.
설명하기 조금 어려운데 코드를 바로 보겠습니다..
[1, 2, 3, 4, 5].publisher
.handleEvents(receiveOutput: { _ in
print("receiveFirstOutput")
})
.scan(0, { (value, newValue) -> Int in
print("This Closure is Running ")
return value + newValue
})
.handleEvents(receiveOutput: { _ in
print("receiveSecondOutput")
})
.sink(receiveCompletion: { print($0)},
receiveValue: { print( $0 )})
.store(in: &cancellable)
//결과
receiveFirstOutput
This Closure is Running
receiveSecondOutput
1
receiveFirstOutput
This Closure is Running
receiveSecondOutput
3
receiveFirstOutput
This Closure is Running
receiveSecondOutput
6
receiveFirstOutput
This Closure is Running
receiveSecondOutput
10
receiveFirstOutput
This Closure is Running
receiveSecondOutput
15
finished
자 이렇듯 업스트림에서 값이 방출되면 종료될 때까지 하나씩 누적 연산되고 그 결과값을 계속 방출이 됩니다.
즉 중간 연산 결과가 계속 방출이 되겠죠?
그 다음은 reduce 입니다
reduce는 scan이랑 비슷합니다.
다른 점은 reduce는 중간과정은 모두 빼고 마지막 결과값만 방출하게 됩니다.
[1, 2, 3, 4, 5].publisher
.handleEvents(receiveOutput: { _ in
print("receiveFirstOutput")
})
.reduce(0, { (value, newValue) -> Int in
print("This Closure is Running ")
return value + newValue
})
.handleEvents(receiveOutput: { _ in
print("receiveSecondOutput")
})
.sink(receiveCompletion: { print($0)},
receiveValue: { print( $0 )})
.store(in: &cancellable)
//결과
receiveFirstOutput
This Closure is Running
receiveFirstOutput
This Closure is Running
receiveFirstOutput
This Closure is Running
receiveFirstOutput
This Closure is Running
receiveFirstOutput
This Closure is Running
receiveSecondOutput
15
finished
끝입니다.
flatMap을 하고싶은데 적당한 예제가 생각이 안나네요.
다음 시간엔 flatMap을 할 수 있길 바래봅니다..
이 글 마지막에 scan과 reduce에 조언을 주신 라이노님에게 다시 한 번 감사를 드립니다.
https://developer.apple.com/documentation/combine/publishers
Publishers - Combine | Apple Developer Documentation
A publisher that republishes items from another publisher only if each new item is in increasing order from the previously-published item, and fails if the ordering logic throws an error.
developer.apple.com
'Combine' 카테고리의 다른 글
Publisher & Subscriber (0) | 2020.02.19 |
---|---|
Combine을 시작하기 전에 (0) | 2020.02.14 |
CombineLatest (0) | 2020.02.11 |
[Combine] Sequence (0) | 2019.12.20 |
[Combine]Just (0) | 2019.12.16 |
- Total
- Today
- Yesterday
- BBIK
- combine
- Just
- ios
- ErrorHandling
- swift
- 결합연산자
- CombineLatest
- AutoLayout
- 알고리즘
- iOSCombine
- 스유
- SEQUENCE
- 텔큐온
- 스위프트유아이
- 유니온파인드
- MVC
- 스위프트
- 삨
- compactMap
- Apple
- 현업이그리운
- SwiftUI
- 자료구조
- UIViewControllerRepresentable
- 콤바인
- Queue
- programmers
- 스택뷰
- replaceNil
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |