Files
keyboard/Pods/SDWebImage/SDWebImage/Core/SDCallbackQueue.m
2025-10-27 21:55:05 +08:00

119 lines
3.3 KiB
Objective-C

/*
* This file is part of the SDWebImage package.
* (c) Olivier Poitrey <rs@dailymotion.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
#import "SDCallbackQueue.h"
@interface SDCallbackQueue ()
@property (nonatomic, strong, nonnull) dispatch_queue_t queue;
@end
static inline void SDSafeAsyncMainThread(dispatch_block_t _Nonnull block) {
if (NSThread.isMainThread) {
block();
} else {
dispatch_async(dispatch_get_main_queue(), block);
}
}
static void SDSafeExecute(dispatch_queue_t queue, dispatch_block_t _Nonnull block, BOOL async) {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
dispatch_queue_t currentQueue = dispatch_get_current_queue();
#pragma clang diagnostic pop
if (queue == currentQueue) {
block();
return;
}
// Special handle for main queue only
if (NSThread.isMainThread && queue == dispatch_get_main_queue()) {
block();
return;
}
if (async) {
dispatch_async(queue, block);
} else {
dispatch_sync(queue, block);
}
}
@implementation SDCallbackQueue
- (instancetype)initWithDispatchQueue:(dispatch_queue_t)queue {
self = [super init];
if (self) {
NSCParameterAssert(queue);
_queue = queue;
_policy = SDCallbackPolicySafeExecute;
}
return self;
}
+ (SDCallbackQueue *)mainQueue {
SDCallbackQueue *queue = [[SDCallbackQueue alloc] initWithDispatchQueue:dispatch_get_main_queue()];
queue->_policy = SDCallbackPolicySafeAsyncMainThread;
return queue;
}
+ (SDCallbackQueue *)currentQueue {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
SDCallbackQueue *queue = [[SDCallbackQueue alloc] initWithDispatchQueue:dispatch_get_current_queue()];
#pragma clang diagnostic pop
return queue;
}
+ (SDCallbackQueue *)globalQueue {
SDCallbackQueue *queue = [[SDCallbackQueue alloc] initWithDispatchQueue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0)];
return queue;
}
- (void)sync:(nonnull dispatch_block_t)block {
switch (self.policy) {
case SDCallbackPolicySafeExecute:
SDSafeExecute(self.queue, block, NO);
break;
case SDCallbackPolicyDispatch:
dispatch_sync(self.queue, block);
break;
case SDCallbackPolicyInvoke:
block();
break;
case SDCallbackPolicySafeAsyncMainThread:
SDSafeAsyncMainThread(block);
break;
default:
NSCAssert(NO, @"unexpected policy %tu", self.policy);
break;
}
}
- (void)async:(nonnull dispatch_block_t)block {
switch (self.policy) {
case SDCallbackPolicySafeExecute:
SDSafeExecute(self.queue, block, YES);
break;
case SDCallbackPolicyDispatch:
dispatch_async(self.queue, block);
break;
case SDCallbackPolicyInvoke:
block();
break;
case SDCallbackPolicySafeAsyncMainThread:
SDSafeAsyncMainThread(block);
break;
default:
NSCAssert(NO, @"unexpected policy %tu", self.policy);
break;
}
}
@end