@@ -106,23 +106,25 @@ actor ImageDownloader {
106106
107107 private func data( for request: URLRequest , options: ImageRequestOptions ) async throws -> Data {
108108 let requestKey = request. urlRequest? . url? . absoluteString ?? " "
109- let task = tasks [ requestKey] ?? ImageDataTask ( task : Task {
109+ let task = tasks [ requestKey] ?? ImageDataTask ( key : requestKey , Task {
110110 try await self . _data ( for: request, options: options, key: requestKey)
111111 } )
112+ task. downloader = self
113+
112114 let subscriptionID = UUID ( )
113115 task. subscriptions. insert ( subscriptionID)
114116 tasks [ requestKey] = task
115117
116- return try await withTaskCancellationHandler {
117- try await task . task . value
118- } onCancel : {
119- Task {
120- await self . unsubscribe ( subscriptionID , key : requestKey )
121- }
118+ return try await task . getData ( subscriptionID : subscriptionID )
119+ }
120+
121+ fileprivate nonisolated func unsubscribe ( _ subscriptionID : UUID , key : String ) {
122+ Task {
123+ await _unsubscribe ( subscriptionID , key : key )
122124 }
123125 }
124126
125- private func unsubscribe ( _ subscriptionID: UUID , key: String ) {
127+ private func _unsubscribe ( _ subscriptionID: UUID , key: String ) {
126128 guard let task = tasks [ key] ,
127129 task. subscriptions. remove ( subscriptionID) != nil ,
128130 task. subscriptions. isEmpty else {
@@ -151,14 +153,24 @@ actor ImageDownloader {
151153}
152154
153155private final class ImageDataTask {
156+ let key : String
154157 var subscriptions = Set < UUID > ( )
155- var isCancelled = false
156- var task : Task < Data , Error >
158+ let task : Task < Data , Error >
159+ weak var downloader : ImageDownloader ?
157160
158- init ( subscriptions : Set < UUID > = Set < UUID > ( ) , task: Task < Data , Error > ) {
159- self . subscriptions = subscriptions
161+ init ( key : String , _ task: Task < Data , Error > ) {
162+ self . key = key
160163 self . task = task
161164 }
165+
166+ func getData( subscriptionID: UUID ) async throws -> Data {
167+ try await withTaskCancellationHandler {
168+ try await task. value
169+ } onCancel: { [ weak self] in
170+ guard let self else { return }
171+ self . downloader? . unsubscribe ( subscriptionID, key: self . key)
172+ }
173+ }
162174}
163175
164176// MARK: - ImageDownloader (Closures)
0 commit comments