@@ -61,9 +61,27 @@ public final class ImageManager : ObservableObject {
61
61
62
62
var currentURL : URL ?
63
63
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
+ }
67
85
68
86
public init ( ) { }
69
87
@@ -96,9 +114,11 @@ public final class ImageManager : ObservableObject {
96
114
progress = 0
97
115
}
98
116
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 {
100
120
DispatchQueue . main. async {
101
- progressBlock ( receivedSize, expectedSize)
121
+ progressCallback ( receivedSize, expectedSize)
102
122
}
103
123
}
104
124
} ) { [ weak self] ( image, data, error, cacheType, finished, _) in
@@ -112,6 +132,10 @@ public final class ImageManager : ObservableObject {
112
132
// So previous View struct call `onDisappear` and cancel the currentOperation
113
133
return
114
134
}
135
+ // Capture completion callbacks in thread-safe way
136
+ let successCallback = self . successBlock
137
+ let failureCallback = self . failureBlock
138
+
115
139
withTransaction ( self . transaction) {
116
140
self . image = image
117
141
self . error = error
@@ -122,9 +146,9 @@ public final class ImageManager : ObservableObject {
122
146
self . indicatorStatus. isLoading = false
123
147
self . indicatorStatus. progress = 1
124
148
if let image = image {
125
- self . successBlock ? ( image, data, cacheType)
149
+ successCallback ? ( image, data, cacheType)
126
150
} else {
127
- self . failureBlock ? ( error ?? NSError ( ) )
151
+ failureCallback ? ( error ?? NSError ( ) )
128
152
}
129
153
}
130
154
}
0 commit comments