How to use escaping closures in Swift | Continued Learning #20
completionHandler
DispatchQueue.main.asyncAfter
를 사용한다.weak self
를 통해 뷰에서 사라지는 경우 참조 사이클을 끊는다.func getData() {
downloadData5 { [weak self] data in
self?.text = data.data
}
}
...
func downloadData4(completionHandler: @escaping (_ data: DownloadResult) -> Void) {
DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
let result = DownloadResult(data: "New Data!")
completionHandler(result)
}
}
func downloadData5(completionHandler: @escaping DownloadCompletion) {
DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
let result = DownloadResult(data: "New Data!")
completionHandler(result)
}
}
struct DownloadResult {
let data: String
}
typealias DownloadCompletion = (DownloadResult) -> ()
nonescaping
)@escaping
선언을 통해 밖으로 값 전달 가능 → 클로저의 특성 이용, 내부 작업이 끝날 때(= 비동기 작업이 끝나서 네트워크, 인터넷 등 데이터 다운로드가 완료되었을 때) 값을 전달 가능completionHandler
클로저의 typealias
로 클로저 타입 전달 가능import SwiftUI
class EscapingViewModel: ObservableObject {
@Published var text = "Hello!"
init() {
print("INIT")
}
deinit {
print("DEINIT")
}
func getData() {
// downloadData3 { [weak self] data in
// self?.text = data
// }
// doSomething(text)
downloadData5 { [weak self] data in
self?.text = data.data
}
}
func downloadData() -> String {
return "New Data"
}
func downloadData2(completionHandler: (_ data: String) -> Void) {
completionHandler("New DATA!")
}
func downloadData3(completionHandler: @escaping (_ data: String) -> Void) {
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
completionHandler("New Data!")
}
}
func downloadData4(completionHandler: @escaping (_ data: DownloadResult) -> Void) {
DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
let result = DownloadResult(data: "New Data!")
completionHandler(result)
}
}
func downloadData5(completionHandler: @escaping DownloadCompletion) {
DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
let result = DownloadResult(data: "New Data!")
completionHandler(result)
}
}
func doSomething(_ data: String) {
print(data)
}
}
struct DownloadResult {
let data: String
}
typealias DownloadCompletion = (DownloadResult) -> ()
struct EscapingBootCamp: View {
@StateObject private var viewModel = EscapingViewModel()
var body: some View {
Text(viewModel.text)
.font(.largeTitle)
.fontWeight(.semibold)
.foregroundColor(.red)
.onTapGesture {
viewModel.getData()
}
}
}