mirror of
https://github.com/SDWebImage/SDWebImage.git
synced 2026-04-07 19:27:40 +00:00
Introduce SafeAsyncMainThread policy
This used for user who really need `mainThread` but not `mainQueue`
This commit is contained in:
@@ -17,8 +17,10 @@ typedef NS_ENUM(NSUInteger, SDCallbackPolicy) {
|
||||
SDCallbackPolicyDispatch = 1,
|
||||
/// Ignore any async/sync and just directly invoke `block` in current queue (without `dispatch_async`/`dispatch_sync`)
|
||||
SDCallbackPolicyInvoke = 2,
|
||||
/// Ensure callback in main queue and main thread, will do `dispatch_async` if the current queue is not main queue; else do invoke `block`. Never use `dispatch_sync`, suitable for UI-related work
|
||||
SDCallbackPolicyMainAsyncSafe = 3
|
||||
/// Ensure callback in main queue (no gurantee on main thread). Do `dispatch_async` if the current queue is not main queue; else do invoke `block`. Never use `dispatch_sync`, suitable for general UI-related code
|
||||
SDCallbackPolicySafeAsyncMainQueue = 3,
|
||||
/// Ensure callback in main thread. Do `dispatch_async` if the `NSThread.isMainTrhead == true` ; else do invoke `block`. Never use `dispatch_sync`, suitable for special UI-related code
|
||||
SDCallbackPolicySafeAsyncMainThread = 4,
|
||||
};
|
||||
|
||||
/// SDCallbackQueue is a wrapper used to control how the completionBlock should perform on queues, used by our `Cache`/`Manager`/`Loader`.
|
||||
@@ -34,7 +36,9 @@ typedef NS_ENUM(NSUInteger, SDCallbackPolicy) {
|
||||
/// The global concurrent queue (user-initiated QoS). Using `dispatch_get_global_queue`.
|
||||
@property (nonnull, class, readonly) SDCallbackQueue *globalQueue;
|
||||
|
||||
/// The current queue's callback policy, defaults to `SDCallbackPolicyMainAsyncSafe`, which behaves like the old macro `dispatch_main_async_safe`
|
||||
/// The current queue's callback policy.
|
||||
/// defaults to `SDCallbackPolicySafeAsyncMainQueue` from v5.20.1, which behaves like the old macro `dispatch_main_async_safe`
|
||||
/// @note old 5.x version use `SDCallbackPolicySafeExecute`, which may behave incorrectly when you sync the block into global queue.
|
||||
@property (assign, readwrite) SDCallbackPolicy policy;
|
||||
|
||||
- (nonnull instancetype)init NS_UNAVAILABLE;
|
||||
|
||||
@@ -21,7 +21,7 @@ static void SDReleaseBlock(void *context) {
|
||||
CFRelease(context);
|
||||
}
|
||||
|
||||
static inline void SDSafeMainAsync(dispatch_block_t _Nonnull block) {
|
||||
static inline void SDSafeMainQueueAsync(dispatch_block_t _Nonnull block) {
|
||||
if (NSThread.isMainThread) {
|
||||
// Match exists `dispatch_main_async_safe` behavior
|
||||
const char *currentLabel = dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL);
|
||||
@@ -34,6 +34,14 @@ static inline void SDSafeMainAsync(dispatch_block_t _Nonnull block) {
|
||||
dispatch_async(dispatch_get_main_queue(), block);
|
||||
}
|
||||
|
||||
static inline void SDSafeMainThreadAsync(dispatch_block_t _Nonnull block) {
|
||||
if (NSThread.isMainThread) {
|
||||
block();
|
||||
} else {
|
||||
dispatch_async(dispatch_get_main_queue(), block);
|
||||
}
|
||||
}
|
||||
|
||||
static void SDSafeExecute(SDCallbackQueue *callbackQueue, dispatch_block_t _Nonnull block, BOOL async) {
|
||||
// Extend gcd queue's life cycle
|
||||
dispatch_queue_t queue = callbackQueue.queue;
|
||||
@@ -71,7 +79,7 @@ static void SDSafeExecute(SDCallbackQueue *callbackQueue, dispatch_block_t _Nonn
|
||||
CFUUIDRef UUID = CFUUIDCreate(kCFAllocatorDefault);
|
||||
dispatch_queue_set_specific(queue, SDCallbackQueueKey, (void *)UUID, SDReleaseBlock);
|
||||
_queue = queue;
|
||||
_policy = SDCallbackPolicyMainAsyncSafe;
|
||||
_policy = SDCallbackPolicySafeAsyncMainQueue;
|
||||
// global queue can execute on main thread, like call `dispatch_sync(globalQueue)` in main thread
|
||||
_thread = NSThread.currentThread;
|
||||
}
|
||||
@@ -111,8 +119,11 @@ static void SDSafeExecute(SDCallbackQueue *callbackQueue, dispatch_block_t _Nonn
|
||||
case SDCallbackPolicyInvoke:
|
||||
block();
|
||||
break;
|
||||
case SDCallbackPolicyMainAsyncSafe:
|
||||
SDSafeMainAsync(block);
|
||||
case SDCallbackPolicySafeAsyncMainQueue:
|
||||
SDSafeMainQueueAsync(block);
|
||||
break;
|
||||
case SDCallbackPolicySafeAsyncMainThread:
|
||||
SDSafeMainThreadAsync(block);
|
||||
break;
|
||||
default:
|
||||
SDSafeExecute(self, block, NO);
|
||||
@@ -131,8 +142,11 @@ static void SDSafeExecute(SDCallbackQueue *callbackQueue, dispatch_block_t _Nonn
|
||||
case SDCallbackPolicyInvoke:
|
||||
block();
|
||||
break;
|
||||
case SDCallbackPolicyMainAsyncSafe:
|
||||
SDSafeMainAsync(block);
|
||||
case SDCallbackPolicySafeAsyncMainQueue:
|
||||
SDSafeMainQueueAsync(block);
|
||||
break;
|
||||
case SDCallbackPolicySafeAsyncMainThread:
|
||||
SDSafeMainThreadAsync(block);
|
||||
break;
|
||||
default:
|
||||
SDSafeExecute(self, block, YES);
|
||||
|
||||
Reference in New Issue
Block a user