12
12
@interface SDCallbackQueue ()
13
13
14
14
@property (nonatomic , strong , nonnull ) dispatch_queue_t queue;
15
- @property (nonatomic , strong , nonnull ) NSThread *thread;
16
15
17
16
@end
18
17
19
- static void * SDCallbackQueueKey = &SDCallbackQueueKey;
20
- static void SDReleaseBlock (void *context) {
21
- CFRelease (context);
22
- }
23
-
24
18
static inline void SDSafeMainQueueAsync (dispatch_block_t _Nonnull block) {
25
19
if (NSThread .isMainThread ) {
26
20
// Match exists `dispatch_main_async_safe` behavior
@@ -42,26 +36,19 @@ static inline void SDSafeMainThreadAsync(dispatch_block_t _Nonnull block) {
42
36
}
43
37
}
44
38
45
- static void SDSafeExecute (SDCallbackQueue *callbackQueue, dispatch_block_t _Nonnull block, BOOL async) {
46
- // Extend gcd queue's life cycle
47
- dispatch_queue_t queue = callbackQueue.queue ;
48
- // Special handle for main queue label only (custom queue can have the same label)
49
- const char *label = dispatch_queue_get_label (queue);
50
- if (label && label == dispatch_queue_get_label (dispatch_get_main_queue ())) {
51
- const char *currentLabel = dispatch_queue_get_label (DISPATCH_CURRENT_QUEUE_LABEL);
52
- if (label == currentLabel) {
53
- block ();
54
- return ;
55
- }
39
+ static void SDSafeExecute (dispatch_queue_t queue, dispatch_block_t _Nonnull block, BOOL async) {
40
+ #pragma clang diagnostic push
41
+ #pragma clang diagnostic ignored "-Wdeprecated-declarations"
42
+ dispatch_queue_t currentQueue = dispatch_get_current_queue ();
43
+ #pragma clang diagnostic pop
44
+ if (queue == currentQueue) {
45
+ block ();
46
+ return ;
56
47
}
57
- // Check specific to detect queue equal
58
- void *specific = dispatch_queue_get_specific (queue, SDCallbackQueueKey);
59
- if (specific && CFGetTypeID (specific) == CFUUIDGetTypeID ()) {
60
- void *currentSpecific = dispatch_get_specific (SDCallbackQueueKey);
61
- if (currentSpecific && CFGetTypeID (currentSpecific) == CFUUIDGetTypeID () && CFEqual (specific, currentSpecific)) {
62
- block ();
63
- return ;
64
- }
48
+ // Special handle for main queue only
49
+ if (NSThread .isMainThread && queue == dispatch_get_main_queue ()) {
50
+ block ();
51
+ return ;
65
52
}
66
53
if (async) {
67
54
dispatch_async (queue, block);
@@ -76,22 +63,15 @@ - (instancetype)initWithDispatchQueue:(dispatch_queue_t)queue {
76
63
self = [super init ];
77
64
if (self) {
78
65
NSCParameterAssert (queue);
79
- CFUUIDRef UUID = CFUUIDCreate (kCFAllocatorDefault );
80
- dispatch_queue_set_specific (queue, SDCallbackQueueKey, (void *)UUID, SDReleaseBlock);
81
66
_queue = queue;
82
- _policy = SDCallbackPolicySafeAsyncMainQueue;
83
- // global queue can execute on main thread, like call `dispatch_sync(globalQueue)` in main thread
84
- _thread = NSThread .currentThread ;
67
+ _policy = SDCallbackPolicySafeExecute;
85
68
}
86
69
return self;
87
70
}
88
71
89
72
+ (SDCallbackQueue *)mainQueue {
90
- static dispatch_once_t onceToken;
91
- static SDCallbackQueue *queue;
92
- dispatch_once (&onceToken, ^{
93
- queue = [[SDCallbackQueue alloc ] initWithDispatchQueue: dispatch_get_main_queue ()];
94
- });
73
+ SDCallbackQueue *queue = [[SDCallbackQueue alloc ] initWithDispatchQueue: dispatch_get_main_queue ()];
74
+ queue->_policy = SDCallbackPolicySafeAsyncMainQueue;
95
75
return queue;
96
76
}
97
77
@@ -111,7 +91,7 @@ + (SDCallbackQueue *)globalQueue {
111
91
- (void )sync : (nonnull dispatch_block_t )block {
112
92
switch (self.policy ) {
113
93
case SDCallbackPolicySafeExecute:
114
- SDSafeExecute (self, block, NO );
94
+ SDSafeExecute (self. queue , block, NO );
115
95
break ;
116
96
case SDCallbackPolicyDispatch:
117
97
dispatch_sync (self.queue , block);
@@ -126,15 +106,15 @@ - (void)sync:(nonnull dispatch_block_t)block {
126
106
SDSafeMainThreadAsync (block);
127
107
break ;
128
108
default :
129
- SDSafeExecute (self, block, NO );
109
+ NSCAssert ( NO , @" unexpected policy %tu " , self.policy );
130
110
break ;
131
111
}
132
112
}
133
113
134
114
- (void )async : (nonnull dispatch_block_t )block {
135
115
switch (self.policy ) {
136
116
case SDCallbackPolicySafeExecute:
137
- SDSafeExecute (self, block, YES );
117
+ SDSafeExecute (self. queue , block, YES );
138
118
break ;
139
119
case SDCallbackPolicyDispatch:
140
120
dispatch_async (self.queue , block);
@@ -149,7 +129,7 @@ - (void)async:(nonnull dispatch_block_t)block {
149
129
SDSafeMainThreadAsync (block);
150
130
break ;
151
131
default :
152
- SDSafeExecute (self, block, YES );
132
+ NSCAssert ( NO , @" unexpected policy %tu " , self.policy );
153
133
break ;
154
134
}
155
135
}
0 commit comments