Study

๐ŸŽ WWDC21: Meet async/await in Swift

_yunie 2024. 8. 20. 23:56

๐ŸŽ WWDC21: Meet async/await in Swift

  • ๋น„๋™๊ธฐ ํ•จ์ˆ˜์˜ ๊ณตํ†ต์ 
    • ํ˜ธ์ถœํ•˜๋ฉด ์ž‘์—… ์‹œ์ž‘ ํ›„ ์Šค๋ ˆ๋“œ์˜ ์ฐจ๋‹จ์„ ๋น ๋ฅด๊ฒŒ ํ•ด์ œ
      • ์žฅ๊ธฐ ์‹คํ–‰ ์ž‘์—…์ด ์™„๋ฃŒ๋˜๋Š” ๋™์•ˆ ์Šค๋ ˆ๋“œ๊ฐ€ ๋‹ค๋ฅธ ์ž‘์—… ์ˆ˜ํ–‰ ๊ฐ€๋Šฅ

 

Completion Handle Example

  • ์ผ๋ถ€ ์ž‘์—…์— ์‹œ๊ฐ„์ด ๊ฑธ๋ฆผ
    • prepareThumbnail
    • dataTask
  • ์™„๋ฃŒ ์‹œ, completionHandler๋ฅผ ํ†ตํ•ด ๊ฒฐ๊ณผ ๋ฐ˜ํ™˜
    • ํ•˜์ง€๋งŒ ์‹คํŒจ ์‹œ์—๋Š” ์–ด๋– ํ•œ ์•Œ๋ฆผ๋„ ๋ฐ›์„ ์ˆ˜ ์—†์Œ
      • ์ด๋ฏธ์ง€๊ฐ€ ๋ณด์—ฌ์ง€์ง€ ์•Š๊ณ  ๋ฌดํ•œ ๋กœ๋”ฉ

  • ๋„ค ๊ฐ€์ง€ ์ž‘์—…์„ ๋™๊ธฐ์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๋˜ ๊ทธ ๋‚ด๋ถ€์˜ ๋‘ ์ž‘์—…์€ ๋น„๋™๊ธฐ์ ์œผ๋กœ ์ฒ˜๋ฆฌ
    • ์ฝ”๋“œ์˜ ์˜๋„๋ฅผ ๋ช…ํ™•ํ•˜๊ฒŒ ํŒŒ์•…ํ•˜๊ธฐ ์–ด๋ ต๋‹ค๋Š” ๋ฌธ์ œ๊ฐ€ ์žˆ์—ˆ์Œ
      • ์ด๋ฅผ ์œ„ํ•ด Result Type์„ ํ™œ์šฉํ•จ

  • Result Type์„ ํ†ตํ•ด ์˜์‹์ ์œผ๋กœ ์—๋Ÿฌ๋ฅผ ๋ณด๋‚ด์ค„ ์ˆ˜ ์žˆ๊ฒŒ๋จ
    • ํ•˜์ง€๋งŒ ์—ฌ์ „ํžˆ ์ฝ”๋“œ๋ฅผ ์ง๊ด€์ ์œผ๋กœ ์ดํ•ดํ•˜๊ธฐ ์–ด๋ ต๋‹ค๋Š” ๋ฌธ์ œ๊ฐ€ ์žˆ์Œ
      • ์ด๋ฅผ ํ•ด๊ฒฐํ•˜๊ณ ์ž async / await์ด ๋“ฑ์žฅํ•จ

 

Async/await Example

  • ๊ธฐ๋ณธ ๊ฐœ๋…
    • async
      • ํ•จ์ˆ˜๊ฐ€ ๋น„๋™๊ธฐ์ž„์„ ๋ช…์‹œ
    • await
      • async๋กœ ๋ช…์‹œ๋œ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœ
        • ๊ทธ๋ ‡๋‹ค๊ณ  ๊ผญ ๋น„๋™๊ธฐ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ ์•„๋‹˜
          • maybeImage?.thumbnail ์ฒ˜๋Ÿผ ๋น„๋™๊ธฐ์  ์†์„ฑ์„ ๋ฐ›์•„์˜ฌ ๋•Œ๋„ ์‚ฌ์šฉ ๊ฐ€๋Šฅ
      • ๋น„๋™๊ธฐ ์ž‘์—…์ด ์ผ์‹œ์ค‘๋‹จ๋  ์ˆ˜ ์žˆ์Œ์„ ์˜๋ฏธ
  • ํ•จ์ˆ˜ ์ •์˜
    • async ํ‚ค์›Œ๋“œ๋ฅผ ํ†ตํ•ด ํ•จ์ˆ˜ ์ž์ฒด๊ฐ€ ๋น„๋™๊ธฐ์ž„์„ ๋ช…์‹œ
      • ํ•จ์ˆ˜์˜ ํ˜•ํƒœ๊ฐ€ ์ข€ ๋” ๊ฐ„๋‹จํ•ด์ง
    • async ํ‚ค์›Œ๋“œ๋Š” ํ•ญ์ƒ throws ๋ฐ”๋กœ ์•ž
      • ์—๋Ÿฌ๊ฐ€ ์—†๋‹ค๋ฉด → ์•ž์— ์กด์žฌ
    • ๋น„๋™๊ธฐ ํ•จ์ˆ˜๊ฐ€ ์„ฑ๊ณตํ•œ๋‹ค๋ฉด ๋ช…์‹œํ•ด์ค€ ๋ฐ์ดํ„ฐ ํƒ€์ž…์˜ ๊ฒฐ๊ณผ๊ฐ’ ๋ฐ˜ํ™˜
    • ์‹คํŒจํ•œ๋‹ค๋ฉด ๊ทธ์ € ์—๋Ÿฌ๋ฅผ ๋˜์ง (throws)
    • ex) func fetchTumbnail(for id: String) async throws → UIImage
  • Completion Handler์™€์˜ ๋น„๊ต
    • Completion Handler์— ๋น„ํ•ด ๋น„๊ต์  ๋‹จ์ˆœํ•œ, ์ง๊ด€์ ์ธ ์ฝ”๋“œ ์‚ฌ์šฉ ๊ฐ€๋Šฅ
    • ์ˆœ์„œ๋Œ€๋กœ ์ˆ˜ํ–‰๋˜์–ด์•ผ ํ•˜๋Š” ๋„ค ์ž‘์—…์ด ์ˆœ์„œ๋Œ€๋กœ ๋‚˜์—ด๋จ
      • ์ฝ”๋“œ์˜ ์˜๋„๋ฅผ ๋ณด๋‹ค ๋ช…ํ™•ํ•˜๊ฒŒ ํŒŒ์•…ํ•  ์ˆ˜ ์žˆ์Œ
func fetchThumbnail(for id: String) async throws -> UIImage {
    let request = thumbnailURLRequest(for: id)  
    
    // ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ -> ์Šค๋ ˆ๋“œ ๋ฐ”๋กœ ํ•ด์ œ
    // try : throws์˜ Error๋ฅผ ๋ฐ›์•„์˜ค๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ 
    // await : async๋กœ ๋ช…์‹œ๋œ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ
    // ํ‘œํ˜„์‹์— ์—ฌ๋Ÿฌ ๋น„๋™๊ธฐ ํ•จ์ˆ˜ ํ˜ธ์ถœ์ด ์žˆ๋Š” ๊ฒฝ์šฐ, await์€ ํ•œ ๋ฒˆ๋งŒ ์‚ฌ์šฉํ•ด์ค˜๋„ ๋จ
    // == ์—ฌ๋Ÿฌ ๊ฐœ์˜ ์—๋Ÿฌ๋ฅผ ๋˜์ง€๋Š” ํ•จ์ˆ˜์— ๋Œ€ํ•ด ํ•œ ๋ฒˆ์˜ try๋งŒ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ๊ณผ ๊ฐ™์€ ๋А๋‚Œ 
    let (data, response) = try await URLSession.shared.data(for: request)
    
    // ๋ฐ์ดํ„ฐ ์™„๋ฃŒ ์‹œ ํ˜„์žฌ ํ•จ์ˆ˜๋กœ ๋Œ์•„์™€ ๋‹ค์Œ ์ž‘์—…์„ ์‹œ์ž‘ํ•จ
    // ๋งŒ์•ฝ ์œ„ try ๊ฒฐ๊ณผ๋กœ ์—๋Ÿฌ๊ฐ€ ๋˜์ ธ์ง„๋‹ค๋ฉด ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•จ
    // ๊ฒฐ๊ณผ๋ฅผ ์„ฑ๊ณต์ ์œผ๋กœ ๋ฐ›์•„์™”๋‹ค๋ฉด (data, response)์— ๊ฐ’์ด ๋“ค์–ด๊ฐ
    // URLSession์˜ dataTask ๋ฉ”์„œ๋“œ์—์„œ ์ „๋‹ฌ๋œ completionHandler๊ฐ€ ํ˜ธ์ถœ๋˜์—ˆ์„ ๋•Œ์™€ ์œ ์‚ฌ
    // ํ•˜์ง€๋งŒ await๋Š” ์ข€ ๋” ๊ฐ„๋‹จํ•˜๋ฉด์„œ ์ง๊ด€์ ์ž„ (๋ฐ˜ํ™˜๋œ ๊ฐ’์„ ๋ณ€์ˆ˜์— ํ• ๋‹นํ•ด! / ๋ฌธ์ œ ์ƒ๊น€ ์—๋Ÿฌ ๋„์›Œ)
    guard (response as? HTTPURLResponse)?.statusCode == 200 else { throw FetchError.badID }
    
    // ๋‹ค์šด๋กœ๋“œํ•œ ๋ฐ์ดํ„ฐ๋กœ UIImage ์ƒ์„ฑ
    let maybeImage = UIImage(data: data)
    
    // ์„ฑ๊ณต ์‹œ, ํ•ด๋‹น ์ด๋ฏธ์ง€์˜ ์ธ๋„ค์ผ ๋ Œ๋”๋ง ์ˆ˜ํ–‰ 
    // ์ด ๋•Œ์—๋„ await์„ ํ†ตํ•ด ์Šค๋ ˆ๋“œ ๋ฐ”๋กœ ํ•ด์ œ -> ๋‹ค๋ฅธ ์ž‘์—… ๊ฐ€๋Šฅ
		// ์„ฑ๊ณต ์‹œ ์ธ๋„ค์ผ ๋ฐ˜ํ™˜ / ์‹คํŒจ ์‹œ ์—๋Ÿฌ ๋ฐœ์ƒ 
		// .thumbnail์ด ๋น„๋™๊ธฐ์ด๊ธฐ ๋•Œ๋ฌธ์— await ์‚ฌ์šฉ
    guard let thumbnail = await maybeImage?.thumbnail else { throw FetchError.badImage }
    return thumbnail
}

 

Async Properties

  • Swift 5.5๋ถ€ํ„ฐ ํƒ€์ž… ํ”„๋กœํผํ‹ฐ์˜ getter์—๋„ throw ์‚ฌ์šฉ ๊ฐ€๋Šฅ
  • ํƒ€์ž… ํ”„๋กœํผํ‹ฐ์˜ setter์—๋Š” async ์‚ฌ์šฉ ๋ถˆ๊ฐ€
    • ์˜ค๋กœ์ง€ getter์—๋งŒ ์‚ฌ์šฉ ๊ฐ€๋Šฅ

await works in for loops
  • for๋ฌธ์„ ๋น„๋™๊ธฐ์ ์œผ๋กœ ์ฒ˜๋ฆฌ ๊ฐ€๋Šฅ
  • ์š”์†Œ๋ฅผ ๋น„๋™๊ธฐ์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•œ๋‹ค๋Š” ์ ์„ ์ œ์™ธํ•˜๊ณ ๋Š” ์ผ๋ฐ˜์ ์ธ for๋ฌธ๊ณผ ๋™์ผ

 

  1. ์ผ๋ฐ˜์ ์ธ ํ•จ์ˆ˜ ํ˜ธ์ถœ ์‹œ, ์Šค๋ ˆ๋“œ์˜ ์ œ์–ด๊ถŒ์ด ํ•จ์ˆ˜๋กœ ๋„˜์–ด์˜ด. ์ด ๋•Œ, ์Šค๋ ˆ๋“œ๋Š” ํ•ด๋‹น ํ•จ์ˆ˜๋ฅผ ์ˆ˜ํ–‰ํ•˜๋Š”๋ฐ ์‚ฌ์šฉ๋จ
  2. ๊ฒฐ๊ณผ์ ์œผ๋กœ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๊ฑฐ๋‚˜ ์—๋Ÿฌ ๋ฐœ์ƒ ์‹œ, ์ œ์–ด๊ถŒ์ด ํ•จ์ˆ˜๋กœ ๋‹ค์‹œ ๋„˜์–ด์˜ด
  3. finishing์„ ํ†ตํ•ด ์ œ์–ด๊ถŒ์ด ํฌ๊ธฐ๋˜๋ฉฐ ๋ชจ๋“  ์ž‘์—…์ด ์ข…๋ฃŒ๋จ

  1. ๋น„๋™๊ธฐ ํ•จ์ˆ˜ ํ˜ธ์ถœ ์‹œ ํ•ด๋‹น ํ•จ์ˆ˜์— ์Šค๋ ˆ๋“œ ์ œ์–ด๊ถŒ ๋ถ€์—ฌ
  2. ๋น„๋™๊ธฐ ์ž‘์—… ์ˆ˜ํ–‰๋™์•ˆ ์Šค๋ ˆ๋“œ ์ œ์–ด ํฌ๊ธฐ
  3. ํ•จ์ˆ˜์— ์ œ์–ด๊ถŒ์„ ๋‹ค์‹œ ๋ถ€์—ฌํ•˜๋Š” ๋Œ€์‹ , ์‹œ์Šคํ…œ์— ์Šค๋ ˆ๋“œ์— ๋Œ€ํ•œ ์ œ์–ด๊ถŒ์„ ๋ถ€์—ฌ
  4. ํ•จ์ˆ˜๋„ ์ผ์‹œ์ •์ง€ ⇒ ์‹œ์Šคํ…œ์ด ์Šค๋ ˆ๋“œ๋ฅผ ์ž์œ ๋กญ๊ฒŒ ์‚ฌ์šฉํ•ด ๋‹ค๋ฅธ ์ž‘์—… ์ˆ˜ํ–‰ ๊ฐ€๋Šฅ : await
  5. ํ˜„์žฌ ์ˆ˜ํ–‰๋˜์–ด์•ผ ํ•  ๊ฐ€์žฅ ์ค‘์š”ํ•œ ์ž‘์—… ๋น„๋™๊ธฐ ์ž‘์—…์ด๋ผ๊ณ  ํŒ๋‹จ๋˜๋ฉด ์‹œ์Šคํ…œ์„ ์žฌ๊ฐœ : resume
  6. ํ•ด๋‹น ๋น„๋™๊ธฐ ํ•จ์ˆ˜๊ฐ€ ๋‹ค์‹œ ์Šค๋ ˆ๋“œ๋ฅผ ์ œ์–ดํ•˜๊ณ  ํ•ด๋‹น ์ž‘์—…์„ ๊ณ„์†ํ•จ
    1. ์ดํ›„์—๋„ ์—ฌ๋Ÿฌ ๋ฒˆ ์ผ์‹œ์ •์ง€ ๊ฐ€๋Šฅ
    2. ๋ฐ˜๋ฉด, ์ผ์‹œ์ •์ง€ ์ž์ฒด๊ฐ€ ํ•„์š”์—†์„ ์ˆ˜ ์žˆ์Œ
      1. async๋กœ ํ‘œ์‹œ๋œ๋‹ค๊ณ  ํ•ญ์ƒ ์ผ์‹œ์ •์ง€๋˜๋Š” ๊ฒƒ์€ ์•„๋‹˜
      2. await์ด ์žˆ๋‹ค๊ณ  ํ•จ์ˆ˜๊ฐ€ ๋ฐ˜๋“œ์‹œ ์ผ์‹œ์ •์ง€๋˜๋Š”๊ฒƒ๋„ ์•„๋‹˜
  7. ๋น„๋™๊ธฐ ์ž‘์—… ์ดํ›„, ์Šค๋ ˆ๋“œ์— ๋Œ€ํ•œ ์ œ์–ด๊ถŒ์„ ํ•จ์ˆ˜์—๊ฒŒ ๋‹ค์‹œ ๋ถ€์—ฌํ•ด์คŒ
func fetchThumbnail(for id: String) async throws -> UIImage {
    let request = thumbnailURLRequest(for: id)  
    
    // ๋น„๋™๊ธฐ ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ -> ์Šค๋ ˆ๋“œ ์‹คํ–‰ ์ค‘์ง€
    // ์‹œ์Šคํ…œ์— ์Šค๋ ˆ๋“œ ์ œ์–ด๊ถŒ ๋ถ€์—ฌ ๋ฐ ์‹œ์Šคํ…œ์— URLSessiond์˜ ์ž‘์—… ์ผ์ • ์˜ˆ์•ฝ
    // ์Šค๋ ˆ๋“œ์— ๋Œ€ํ•œ ์ œ์–ด๊ถŒ์„ ์‹œ์Šคํ…œ์ด ๊ฐ€์ง€๊ธฐ ๋•Œ๋ฌธ์— ๋ฐ”๋กœ ์‹œ์ž‘๋˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ์Œ
    // ๋Œ€์‹  ์Šค๋ ˆ๋“œ๋ฅผ ๋‹ค๋ฅธ ์šฉ๋„๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Œ 
    // ํ•ด๋‹น ๋น„๋™๊ธฐ ์ž‘์—… ์™„๋ฃŒ ํ›„, fetchThumbnail๋กœ ๋Œ์•„์˜ด
    // - ํ•จ์ˆ˜๊ฐ€ ์ผ์‹œ์ •์ง€์ธ ์ƒํƒœ์—์„œ ๋‹ค๋ฅธ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ๋น„๋™๊ธฐ ์ž‘์—…์„ await๋กœ ํ‘œ์‹œํ•จ
    // - ๋˜ํ•œ, await ํ‚ค์›Œ๋“œ๋Š” ์ฝ”๋“œ ๋ธ”๋ก์ด ํ•˜๋‚˜์˜ ํŠธ๋žœ์žญ์…˜์œผ๋กœ ์‹คํ–‰๋˜์ง€ ์•Š์Œ์„ ์˜๋ฏธ 
    let (data, response) = try await URLSession.shared.data(for: request)

    guard (response as? HTTPURLResponse)?.statusCode == 200 else { throw FetchError.badID }
    
    let maybeImage = UIImage(data: data)
   
    guard let thumbnail = await maybeImage?.thumbnail else { throw FetchError.badImage }
    return thumbnail
}

await ํ‚ค์›Œ๋“œ๋ฅผ ํ†ตํ•œ ํ•˜๋‚˜์˜ ์ฝ”๋“œ ๋ธ”๋Ÿญ ๋‚ด ํŠธ๋žœ์žญ์…˜์ด ๋ถ„๋ฆฌ๋จ

 

async/await facts

  • async๋Š” ํ•จ์ˆ˜๊ฐ€ ๋น„๋™๊ธฐ์ ์œผ๋กœ ์‹คํ–‰๋  ์ˆ˜ ์žˆ์Œ์„ ์˜๋ฏธํ•˜๋Š” ํ‚ค์›Œ๋“œ
    • = ํ•ด๋‹น ํ•จ์ˆ˜๊ฐ€ ์ผ์‹œ์ •์ง€ ๋  ์ˆ˜ ์žˆ์Œ
    • ํ˜ธ์ถœ์ž๋„ ์ผ์‹œ์ •์ง€๊ฐ€ ๋˜๋ฏ€๋กœ ํ˜ธ์ถœ์ž๋„ ๋น„๋™๊ธฐ์—ฌ์•ผ ํ•จ
  • ๋น„๋™๊ธฐ ์ž‘์—… ๋‚ด์—์„œ ์ผ์‹œ์ •์ง€๋ฅผ ํ•  ์œ„์น˜ ์ง€์ •์„ ์œ„ํ•ด await ํ‚ค์›Œ๋“œ ์‚ฌ์šฉ
  • ๋น„๋™๊ธฐ ์ž‘์—…์ด ์ผ์‹œ์ •์ง€๋˜๋Š” ๋™์•ˆ ์Šค๋ ˆ๋“œ๋Š” ์ฐจ๋‹จ๋˜์ง€ ์•Š์Œ
    • ์‹œ์Šคํ…œ์ด ๋‹ค๋ฅธ ์ž‘์—…์„ ํ•  ์ˆ˜ ์žˆ์Œ
      • ์•ฑ ์ƒํƒœ๊ฐ€ ๋ณ€ํ•  ์ˆ˜ ์žˆ์Œ์„ ์˜๋ฏธ
  • ๋น„๋™๊ธฐ ํ•จ์ˆ˜ ์žฌ์‹œ์ž‘ ์‹œ, ๋น„๋™๊ธฐ ํ•จ์ˆ˜ ๊ฒฐ๊ณผ๋กœ ๋ฐ˜ํ™˜๋œ ๋ฐ์ดํ„ฐ๊ฐ€ ์›๋ž˜ ํ•จ์ˆ˜๋กœ ์œ ์ž…๋˜๊ณ  ์ค‘๋‹จ๋œ ๋ถ€๋ถ„๋ถ€ํ„ฐ ์ด์–ด์„œ ์‹คํ–‰๋จ

 

Testing async code

  • XCTest๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ๋น„๋™๊ธฐ ์ง€์›
    • ๋น„๋™๊ธฐ ์ฝ”๋“œ๊ฐ€ ๋™๊ธฐ์ฒ˜๋Ÿผ ์‰ฝ๊ฒŒ ์ž‘์„ฑ๋˜๊ธธ ์›ํ–ˆ๊ธฐ ๋•Œ๋ฌธ

  • ๋น„๋™๊ธฐ๊ฐ€ ์•„๋‹Œ Context ๋‚ด์—์„œ๋Š” ๋น„๋™๊ธฐ ํ•จ์ˆ˜ ํ˜ธ์ถœ ๋ถˆ๊ฐ€
  • onAppear๋Š” ์ผ๋ฐ˜ ํด๋กœ์ €๋ฅผ ์‚ฌ์šฉ
    • ๋™๊ธฐ์™€ ๋น„๋™๊ธฐ๋ฅผ ์—ฐ๊ฒฐํ•ด์ฃผ๋Š” ๋งค๊ฐœ์ฒด๊ฐ€ ํ•„์š”ํ•˜๊ฒŒ ๋จ
      • ์ด ๋•Œ, Task๋กœ ๋น„๋™๊ธฐ ์ž‘์—…์„ ๊ฐ์‹ธ์คŒ

์žฌ๋นŒ๋“œ ์‹œ ์—๋Ÿฌ ๋ฉ”์‹œ์ง€ ์‚ฌ๋ผ์ง

  • Task๋ฅผ ํ†ตํ•ด ๋™๊ธฐ ์ž‘์—… ๋‚ด์—์„œ ๋น„๋™๊ธฐ ์ž‘์—…์„ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๊ฒŒ๋จ

 

CompletionHandler ⇒ Async

Swift 5.5 ์ด์ „๊นŒ์ง€์˜ ๋ฐฉ์‹

Swift 5.5๋ถ€ํ„ฐ ๊ฐ€๋Šฅํ•œ ๋ฐฉ์‹

  • ๋น„๋™๊ธฐ ์ž‘์—…์€ ํ˜ธ์ถœ๊ณผ ๋™์‹œ์— ๊ฒฐ๊ณผ๊ฐ€ ๋ฐ˜ํ™˜๋˜์ง€ ์•Š์œผ๋ฏ€๋กœ ํ•จ์ˆ˜๋ช…์—์„œ get์„ ์“ฐ์ง€์•Š๋Š” ๊ฒƒ์ด ์ข‹์Œ

 

Async alternatives and continuations

  • ํ™œ์šฉ ํ•จ์ˆ˜
func getPersistentPosts(completion: @escaping ([Post], Error?) -> Void) {       
    do {
        let req = Post.fetchRequest()
        req.sortDescriptors = [NSSortDescriptor(key: "date", ascending: true)]
        let asyncRequest = NSAsynchronousFetchRequest<Post>(fetchRequest: req) { result in
            // ์™„๋ฃŒ ํ›„ completionHandler๋กœ ๊ฒฐ๊ณผ ๋ฐ˜ํ™˜ 
            completion(result.finalResult ?? [], nil)
        }
        try self.managedObjectContext.execute(asyncRequest)
    } catch {
        completion([], error)
    }
}

Async/await์„ ๋ฐ˜์˜ํ•ด ์‚ฌ์šฉํ•ด๋ณด์ž

  • ๋ฌธ์ œ์ 
    • getpersistentPosts์˜ ๊ฒฐ๊ณผ๋ฅผ ๊ฐ€์ ธ์™€ ๋ญ˜ ํ•  ์ˆ˜๊ฐ€ ์—†์–ด ํ•จ์ˆ˜๊ฐ€ ๋” ์ง„ํ–‰๋˜์ง€ ์•Š์Œ
  • ํ•„์š”ํ•œ ํ•ด๊ฒฐ๋ฐฉ๋ฒ•
    • getPersistentPosts์˜ ๊ฒฐ๊ณผ๋ฅผ persistentPosts์˜ ํ•จ์ˆ˜๊ฐ€ ์ผ์‹œ์ •์ง€๋œ ์œ„์น˜๋กœ ๋ฐ˜ํ™˜ํ•ด์ฃผ์–ด์•ผํ•จ
    • ๋˜ํ•œ, ํ˜ธ์ถœ์ž๋„ ์ผ์‹œ์ •์ง€๋œ ์ƒํƒœ๋กœ ์ ์ ˆํ•œ ์‹œ์ ์— ์˜ฌ๋ฐ”๋ฅธ ๋ฐ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•ด ์ž‘์—…์„ ์žฌ๊ฐœํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ์–ด์•ผํ•จ
  • CompletionHandler๋ฅผ ๊ฐ€์ ธ์™€ ๊ฒฐ๊ณผ๋ฅผ ํ†ตํ•ด ๋‹ค์‹œ ์‹œ์ž‘ํ•˜๋Š” resume์ด ์—†์Œ
  • ๊ฒฐ๊ตญ ์šฐ๋ฆฌ๊ฐ€ ์›ํ•˜๋Š” ๊ฒฐ๊ณผ๋ฅผ ์œ„ํ•ด์„œ๋Š” ์ด๋Ÿฌํ•œ ํ˜•ํƒœ๋กœ ๋งŒ๋“ค์–ด์ฃผ์–ด์•ผํ•จ
  • ์ด๋ฅผ ์œ„ํ•ด withCheckedThrowingContinuation์„ ์‚ฌ์šฉ
    • ์—๋Ÿฌ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” Completion Handler๋ฅผ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ์Œ
    • ์ค‘์ง€๋œ ๋น„๋™๊ธฐ ํ•จ์ˆ˜๋ฅผ ์žฌ๊ฐœํ•˜๋Š”๋ฐ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Œ
  • ์—๋Ÿฌ๊ฐ€ ์—†๋Š” ์ƒํ™ฉ์ด๋ผ๋ฉด withCheckedContinuations ์‚ฌ์šฉ
func persistentPosts() async throws -> [Post] {       
    typealias PostContinuation = CheckedContinuation<[Post], Error>
    // getPersistentposts์— ๋Œ€ํ•œ ํ˜ธ์ถœ์„ ๊ธฐ๋‹ค๋ฆฌ๋„๋ก ํ•จ 
    return try await withCheckedThrowingContinuation { (continuation: PostContinuation) in
        self.getPersistentPosts { posts, error in
		        // ๊ฒฐ๊ณผ๊ฐ€ ์˜จ๋‹ค๋ฉด ํ˜„์žฌ ์ผ์‹œ์ •์ง€๋œ ํ•จ์ˆ˜๋ฅผ resume ์‹œํ‚ด 
            if let error = error { 
                continuation.resume(throwing: error) 
            } else {
                continuation.resume(returning: posts)
            }
        }
    }
}
  • โš ๏ธ ์ฃผ์˜์‚ฌํ•ญ
    • resume์€ ๋ชจ๋“  ๊ฒฝ๋กœ์—์„œ ์˜ค๋กœ์ง€ ํ•œ ๋ฒˆ๋งŒ ํ˜ธ์ถœ
      • resume์ด ์—†๋Š” ๊ฒฝ์šฐ, warning
      • resume์ด ์—ฌ๋Ÿฌ ๊ฐœ์ผ ๊ฒฝ์šฐ, ๋‘ ๋ฒˆ์งธ ํ˜ธ์ถœ์—์„œ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒ
    •  

'Study' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

๐Ÿ“š Concurrency Docs ๋‚ด ์ผ๋ถ€  (0) 2024.09.11
๐ŸŽ WWDC21 : Explore structured concurrency in Swift  (0) 2024.09.07
๐Ÿ‘€ Continuation ์•Œ์•„๋ณด๊ธฐ  (0) 2024.08.24
๐Ÿ“š ARC Docs ์ •๋ฆฌ  (0) 2024.08.06
๐ŸŽย WWDC : ARC in Swift  (0) 2024.08.02