@@ -61,9 +61,27 @@ public final class ImageManager : ObservableObject {
6161
6262 var currentURL : URL ?
6363 var transaction = Transaction ( )
64- var successBlock : ( ( PlatformImage , Data ? , SDImageCacheType ) -> Void ) ?
65- var failureBlock : ( ( Error ) -> Void ) ?
66- var progressBlock : ( ( Int , Int ) -> Void ) ?
64+
65+ // Thread-safe callback properties
66+ private let callbackQueue = DispatchQueue ( label: " ImageManager.callbacks " , qos: . userInitiated)
67+ private var _successBlock : ( ( PlatformImage , Data ? , SDImageCacheType ) -> Void ) ?
68+ private var _failureBlock : ( ( Error ) -> Void ) ?
69+ private var _progressBlock : ( ( Int , Int ) -> Void ) ?
70+
71+ var successBlock : ( ( PlatformImage , Data ? , SDImageCacheType ) -> Void ) ? {
72+ get { callbackQueue. sync { _successBlock } }
73+ set { callbackQueue. sync { _successBlock = newValue } }
74+ }
75+
76+ var failureBlock : ( ( Error ) -> Void ) ? {
77+ get { callbackQueue. sync { _failureBlock } }
78+ set { callbackQueue. sync { _failureBlock = newValue } }
79+ }
80+
81+ var progressBlock : ( ( Int , Int ) -> Void ) ? {
82+ get { callbackQueue. sync { _progressBlock } }
83+ set { callbackQueue. sync { _progressBlock = newValue } }
84+ }
6785
6886 public init ( ) { }
6987
@@ -96,9 +114,11 @@ public final class ImageManager : ObservableObject {
96114 progress = 0
97115 }
98116 self . indicatorStatus. progress = progress
99- if let progressBlock = self . progressBlock {
117+ // Capture progress callback in thread-safe way
118+ let progressCallback = self . progressBlock
119+ if let progressCallback = progressCallback {
100120 DispatchQueue . main. async {
101- progressBlock ( receivedSize, expectedSize)
121+ progressCallback ( receivedSize, expectedSize)
102122 }
103123 }
104124 } ) { [ weak self] ( image, data, error, cacheType, finished, _) in
@@ -112,6 +132,10 @@ public final class ImageManager : ObservableObject {
112132 // So previous View struct call `onDisappear` and cancel the currentOperation
113133 return
114134 }
135+ // Capture completion callbacks in thread-safe way
136+ let successCallback = self . successBlock
137+ let failureCallback = self . failureBlock
138+
115139 withTransaction ( self . transaction) {
116140 self . image = image
117141 self . error = error
@@ -122,9 +146,9 @@ public final class ImageManager : ObservableObject {
122146 self . indicatorStatus. isLoading = false
123147 self . indicatorStatus. progress = 1
124148 if let image = image {
125- self . successBlock ? ( image, data, cacheType)
149+ successCallback ? ( image, data, cacheType)
126150 } else {
127- self . failureBlock ? ( error ?? NSError ( ) )
151+ failureCallback ? ( error ?? NSError ( ) )
128152 }
129153 }
130154 }
0 commit comments