Swift에서 Conceurrency(async, await)와 전통적인 Closure 두 가지를 대응하는 방법을 실시하다
아무것도 고려하지 않고 설치하면 코드의 양이 늘어나 번거로울 수 있기 때문에 간단하게 보기 위해 어떻게 설치했는지 설명하고 싶습니다.
먼저 Conceurrency 코드와 Closure 코드의 차이점을 설명합니다.
Swift의 Conceurrency는 다음 코드입니다.
class HogeClass {
func asyncFunction() async -> Int {
return 0
}
}
let hoge = HogeClass()
let value = await hoge.asyncFunction()
전통Closure
의 코드를 사용했다면 다음과 같은 코드일 것 같다(이것은 모두가 본 사람이다).class HogeClass {
func asyncFunction(_ block: (Int) -> Void) async -> Int {
block(0)
}
}
let hoge = HogeClass()
hoge.asyncFunction { hoge in
}
두 가지 설치
과제.
그렇다면 여기서 Concurrency와 Closure 두 가지가 대응하는 상황에서 어떻게 하면 좋을까요?
간단하게 생각하면 아래와 같이 하나하나 실시할 수 있을 것 같습니다.
class HogeClass {
func asyncFunction() async -> Int {
return 0
}
func asyncFunction(_ block: (Int) -> Void) async -> Int {
block(0)
}
}
이 경우 방법의 수량이 증가할수록 설치가 번거롭다.100가지 방법이 있으면 각각 Conceurrency와 Closure를 설치해 200개의 API를 실현해야 한다.그리고 조금 다른 코드를 많이 써야 해서 지루해요.
해결책
많이 찾아봤는데https://github.com/Alamofire/Alamofire 대응하는 느낌이 좋아서 참고했어요.
이 문제는 실제 값이 저장된 용기를 되돌려주고 그 컨테이너는 컨테이너와 Closure에 대응해서 해결할 수 있다.
여기서 말한 컨테이너는
Result
와Option
처럼 실제 값을 저장하는 유형이다.세부적인 부분은 생략했지만 다음과 같이 실시할 수 있다.
// 例えば以下のようなコードをコンテナとして実装
struct AsyncResult<T> {
// Concurrency 対応
var result: T {
get async {
return await withCheckedContinuation { c in
result { value in
c.resume(returning: value)
}
}
}
}
// Closure 対応
func result(_ block: (T) -> Void) {
// ここは工夫して実装する必要があります
block(0)
}
}
// 先の HogeClass は以下のように実装できます。
// メソッドの実装は一つですみます。
class HogeClass {
func asyncFunction() -> AsyncResult<Int> {
return AsyncResult()
}
}
// 使用するときは以下のように Concurrent 方式でも Closure 方式でも結果を取得できます。
let hoge = HogeClass()
let value = await hoge.asyncFunction().result
hoge.asyncFunction.result { value in }
이로써 100가지 방법이 있어도 100개만 설치하면 된다.실제로
AsyncResult
주변 코드를 써야 하기 때문에 110개 정도의 설치량인가요?추가 정보
이 방법의 또 다른 장점은 콘서트를 extension으로 표현할 수 있다는 것이다.
컨투어링에 실제로 해당되는 경우
#if compiler(>=5.5.2) && canImport(_Concurrency)
@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *)
// AsyncResult.swift
struct AsyncResult<T> {
// Closure 対応
func result(_ block: (T) -> Void) {
block(0)
}
}
// AsyncResult+Concurrency.swift
#if compiler(>=5.5.2) && canImport(_Concurrency)
@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *)
extension AsyncResult {
var result: T {
get async {
return await withCheckedContinuation { c in
result { value in
c.resume(returning: value)
}
}
}
}
}
#endif
더욱 상세한 실시 예
실제 코드 예 몇 개를 미리 붙이다.
총결산
컨투어링 방식에서도 클로저 방식과 양자에 대응하는 방법의 제작 방법을 소개했다.
그러나 이 방법은 반환값을 저장하는 용기의 코드를 써야 하는 경우도 있었다.
따라서
似たコードを2回書く手間 と コンテナのコードを書く手間
의 원가를 꼼꼼히 비교해야 한다고 생각합니다.제가 만든 TwitterAPIKit도 처음에는 컨셉트 방식으로 클로저 방식의 쌍방을 쓰려고 했지만 트위터 API가 200개 정도 되는 게 귀찮아서 이번에 소개한 방법을 사용했습니다.
앞으로 일정 기간은 스위프트 컨투어링의 과도기가 될 수 있으니 클로저 형식과 섞을 필요가 있는데 참고가 된다면 좋겠다.
Reference
이 문제에 관하여(Swift에서 Conceurrency(async, await)와 전통적인 Closure 두 가지를 대응하는 방법을 실시하다), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://zenn.dev/mironal/articles/8c9247960de8ef텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)