Skip to content

Latest commit

Β 

History

History
63 lines (45 loc) Β· 3.04 KB

File metadata and controls

63 lines (45 loc) Β· 3.04 KB

Detached Task

비동기 μž‘μ—…μ˜ κΈ°λ³Έ λ‹¨μœ„


κ·Έλ ‡λ‹€λ©΄ Task의 짝꿍인 Detached TaskλŠ” λ¬΄μ—‡μΌκΉŒμš”? πŸ€” 일반적인 TaskλŠ” μƒμ„±λœ μœ„μΉ˜μ˜ μš°μ„ μˆœμœ„, μ•‘ν„°, Task-Local λ³€μˆ˜ λ“± λ‹€μ–‘ν•œ μžμ›μ„ 상속받아 μ‹€ν–‰λ©λ‹ˆλ‹€.

λ°˜λ©΄μ— Detached TaskλŠ” μ΄λŸ¬ν•œ μžμ›μ„ μ „ν˜€ μƒμ†ν•˜μ§€ μ•Šκ³ , μ™„μ „νžˆ 독립적인 μ»¨ν…μŠ€νŠΈμ—μ„œ μ‹€ν–‰λ˜λŠ” μž‘μ—…μž…λ‹ˆλ‹€. 즉, λ°”κΉ₯ μž‘μ—…κ³Όμ˜ μ—°κ²° 없이 슀슀둜 λ…λ¦½λœ 비동기 μž‘μ—…μ„ μ‹€ν–‰ν•  λ•Œ μ‚¬μš©λ©λ‹ˆλ‹€.

let task1 = Task(priority: .userInitiated) {
    print("πŸ˜ƒ Task1의 μž‘μ—… μš°μ„ μˆœμœ„: \(Task.currentPriority)")
    
    let task2 = Task.detached {
        print("πŸ˜ƒ Task2의 μž‘μ—… μš°μ„ μˆœμœ„: \(Task.currentPriority)")
    }
}
// Print "πŸ˜ƒ Task1의 μž‘μ—… μš°μ„ μˆœμœ„: TaskPriority.high"
// Print "πŸ˜ƒ Task2의 μž‘μ—… μš°μ„ μˆœμœ„: TaskPriority.medium"

μœ„ μ˜ˆμ œμ—μ„œ task1은 userInitiated μš°μ„ μˆœμœ„λ‘œ μƒμ„±λœ μž‘μ—…μž…λ‹ˆλ‹€. κ·Έ λ‚΄λΆ€μ—μ„œ μƒμ„±λœ task2λŠ” Detached Task이기 λ•Œλ¬Έμ—, task1의 μžμ›μ„ 상속받지 μ•ŠμŠ΅λ‹ˆλ‹€. λ”°λΌμ„œ task2의 μš°μ„ μˆœμœ„λŠ” medium이 λ©λ‹ˆλ‹€.

κ·Έλ ‡λ‹€λ©΄ Detached TaskλŠ” μ–΄λ–»κ²Œ ν™œμš©ν•  수 μžˆμ„κΉŒμš”? WWDCμ—μ„œλŠ” 이미지 썸넀일을 λ‹€μš΄λ‘œλ“œν•˜μ—¬ μ»¬λ ‰μ…˜ λ·° 셀에 ν‘œμ‹œν•˜κ³ , λ™μ‹œμ— λ””μŠ€ν¬ μΊμ‹œμ— μ €μž₯ν•˜λŠ” μž‘μ—…μ— Detached Taskλ₯Ό ν™œμš©ν•˜λŠ” 예제λ₯Ό μ†Œκ°œν–ˆμŠ΅λ‹ˆλ‹€.

@MainActor
extension MyDelegate: UICollectionViewDelegate {
    public func collectionView(_ view: UICollectionView,
                               willDisplay cell: UICollectionViewCell,
                               forItemAt item: IndexPath) {
        let ids = getThumbnailIDs(for: item)
        thumbnailTasks[item] = Task {
            defer { thumbnailTasks[item] = nil}
            let thumbnails = await fetchThumbnails (for: ids)
            Task.detached(priority: .background) {
                self.writeToLocalCache(thumbnails)
            }
            display (thumbnails, in: cell)
        }
    }
    
    public func collectionView(_ collectionView: UICollectionView,
                               didEndDisplaying cell: UICollectionViewCell,
                               forItemAt indexPath: IndexPath) {
        thumbnailTasks[indexPath]?.cancel()
        thumbnailTasks[indexPath] = nil
    }
}

μœ„ μ˜ˆμ œμ—μ„œλŠ” collectionView(_:willDisplay:) λ©”μ„œλ“œ μ•ˆμ—μ„œ 셀이 화면에 ν‘œμ‹œλ˜κΈ° 직전에 썸넀일을 λΉ„λ™κΈ°λ‘œ λΆˆλŸ¬μ˜΅λ‹ˆλ‹€.

썸넀일 λ‘œλ”© μž‘μ—…μ€ 일반적인 Task둜 μ‹€ν–‰λ˜λ©°, μ΄λŠ” μ·¨μ†Œκ°€ κ°€λŠ₯ν•©λ‹ˆλ‹€. 썸넀일이 μ„±κ³΅μ μœΌλ‘œ λ‘œλ”©λ˜λ©΄, 이 이미지λ₯Ό λ””μŠ€ν¬μ— μ €μž₯ν•˜λŠ” μž‘μ—…μ„ Task.detached둜 μ‹€ν–‰ν•©λ‹ˆλ‹€.

writeToLocalCache(_:)λŠ” λ””μŠ€ν¬ I/O와 같은 무거운 λ°±κ·ΈλΌμš΄λ“œ μž‘μ—…μž…λ‹ˆλ‹€. 이 μž‘μ—…μ€ UI μ»¨ν…μŠ€νŠΈλ‚˜ μš°μ„ μˆœμœ„μ˜ 영ν–₯을 λ°›μ§€ μ•Šμ•„λ„ λ˜λŠ” 독립 μž‘μ—…μ΄λ―€λ‘œ, Task.detached(priority: .background)둜 λΆ„λ¦¬ν•˜μ—¬ μ²˜λ¦¬ν•©λ‹ˆλ‹€.

μ„ ν˜Έν•˜λŠ” μž‘μ—… μ‹€ν–‰μž