@@ -27,7 +27,7 @@ static dispatch_queue_t defaultConcurrentQueue() {
2727 queueCount = queueCount < 8 ? 8 : queueCount > MAX_QUEUE_COUNT ? MAX_QUEUE_COUNT : queueCount;
2828 if ([UIDevice currentDevice ].systemVersion .floatValue >= 8.0 ) {
2929 for (NSUInteger i = 0 ; i < queueCount; i++) {
30- dispatch_queue_attr_t attr = dispatch_queue_attr_make_with_qos_class (DISPATCH_QUEUE_SERIAL, QOS_CLASS_DEFAULT+ 1 , 0 );
30+ dispatch_queue_attr_t attr = dispatch_queue_attr_make_with_qos_class (DISPATCH_QUEUE_SERIAL, QOS_CLASS_DEFAULT, 0 );
3131 queues[i] = dispatch_queue_create (" com.yb.taskScheduler" , attr);
3232 }
3333 } else {
@@ -43,12 +43,35 @@ static dispatch_queue_t defaultConcurrentQueue() {
4343}
4444
4545
46+ static CADisplayLink *displayLink;
47+ static pthread_mutex_t displayLinkLock;
48+
49+ static void keepRunLoopActive () {
50+ static dispatch_once_t onceToken;
51+ dispatch_once (&onceToken, ^{
52+ displayLink = [CADisplayLink displayLinkWithTarget: YBTaskScheduler.self selector: @selector (hash )];
53+ [displayLink addToRunLoop: [NSRunLoop mainRunLoop ] forMode: NSRunLoopCommonModes ];
54+ pthread_mutex_init (&displayLinkLock, NULL );
55+ });
56+ pthread_mutex_lock (&displayLinkLock);
57+ if (displayLink.paused ) {
58+ displayLink.paused = NO ;
59+ }
60+ pthread_mutex_unlock (&displayLinkLock);
61+ }
62+
63+
4664static NSHashTable *taskSchedulers;
4765
4866static void runLoopObserverCallBack (CFRunLoopObserverRef observer, CFRunLoopActivity activity, void *info) {
67+ BOOL keepActive = NO ;
4968 for (YBTaskScheduler *scheduler in taskSchedulers.allObjects ) {
50- [scheduler executeTasks ];
69+ if (!scheduler.empty ) {
70+ keepActive = YES ;
71+ [scheduler executeTasks ];
72+ }
5173 }
74+ displayLink.paused = !keepActive;
5275}
5376
5477static void addRunLoopObserver () {
@@ -62,82 +85,55 @@ static void addRunLoopObserver() {
6285}
6386
6487
65- static CADisplayLink *displayLink;
66- static int32_t displayLinkCounter = 0 ;
67- static pthread_mutex_t displayLinkLock;
68-
69- static void addDisplayLink () {
70- static dispatch_once_t onceToken;
71- dispatch_once (&onceToken, ^{
72- displayLink = [CADisplayLink displayLinkWithTarget: YBTaskScheduler.self selector: @selector (hash )];
73- pthread_mutex_init (&displayLinkLock, NULL );
74- });
75- int32_t counter = OSAtomicIncrement32 (&displayLinkCounter);
76- if (counter >= 1 ) {
77- pthread_mutex_lock (&displayLinkLock);
78- [displayLink addToRunLoop: [NSRunLoop mainRunLoop ] forMode: NSRunLoopCommonModes ];
79- pthread_mutex_unlock (&displayLinkLock);
80- }
81- }
82-
83- static void removeDisplayLink () {
84- int32_t counter = OSAtomicDecrement32 (&displayLinkCounter);
85- if (counter <= 0 ) {
86- pthread_mutex_lock (&displayLinkLock);
87- if (displayLink) {
88- [displayLink removeFromRunLoop: [NSRunLoop mainRunLoop ] forMode: NSRunLoopCommonModes ];
89- }
90- pthread_mutex_unlock (&displayLinkLock);
91- }
92- }
93-
94-
9588@implementation YBTaskScheduler {
9689 id <YBTaskSchedulerStrategyProtocol> _strategy;
90+ NSUInteger _frequencyCounter;
9791}
9892
9993#pragma mark - life cycle
10094
101- - (void )dealloc {
102- NSLog (@" 释放:%@ " , self);
103- removeDisplayLink ();
104- }
105-
106- - (instancetype )initWithStrategy : (YBTaskSchedulerStrategy)strategy {
95+ - (instancetype )initWithStrategyObject : (id <YBTaskSchedulerStrategyProtocol>)strategyObject {
10796 self = [super init ];
10897 if (self) {
109- addDisplayLink ();
11098 addRunLoopObserver ();
111- self.numberOfExecuteEachTime = 1 ;
99+ self.executeNumber = 1 ;
112100 self.maxNumberOfTasks = NSUIntegerMax;
113- switch (strategy) {
114- case YBTaskSchedulerStrategyLIFO:
115- _strategy = [YBTSStack new ];
116- break ;
117- case YBTaskSchedulerStrategyFIFO:
118- _strategy = [YBTSQueue new ];
119- break ;
120- case YBTaskSchedulerStrategyPriority:
121- _strategy = [YBTSPriorityQueue new ];
122- break ;
123- }
101+ self.executeFrequency = 1 ;
102+ _strategy = strategyObject;
124103 [taskSchedulers addObject: self ];
125104 }
126105 return self;
127106}
128107
108+ - (instancetype )initWithStrategy : (YBTaskSchedulerStrategy)strategy {
109+ id <YBTaskSchedulerStrategyProtocol> strategyObject;
110+ switch (strategy) {
111+ case YBTaskSchedulerStrategyLIFO:
112+ strategyObject = [YBTSStack new ];
113+ break ;
114+ case YBTaskSchedulerStrategyFIFO:
115+ strategyObject = [YBTSQueue new ];
116+ break ;
117+ case YBTaskSchedulerStrategyPriority:
118+ strategyObject = [YBTSPriorityQueue new ];
119+ break ;
120+ }
121+ return [self initWithStrategyObject: strategyObject];
122+ }
123+
129124+ (instancetype )schedulerWithStrategy : (YBTaskSchedulerStrategy)strategy {
130125 return [[YBTaskScheduler alloc ] initWithStrategy: strategy];
131126}
132127
133128#pragma mark - public
134129
135130- (void )addTask : (YBTaskBlock)task {
136- if (!task) return ;
137- [_strategy ybts_addTask: task priority: YBTaskPriorityDefault];
131+ [self addTask: task priority: YBTaskPriorityDefault];
138132}
139133
140134- (void )addTask : (YBTaskBlock)task priority : (YBTaskPriority)priority {
135+ if (!task) return ;
136+ keepRunLoopActive ();
141137 [_strategy ybts_addTask: task priority: priority];
142138}
143139
@@ -147,7 +143,17 @@ - (void)clearTasks {
147143
148144#pragma mark - internal
149145
146+ - (BOOL )empty {
147+ return _strategy.ybts_empty ;
148+ }
149+
150150- (void )executeTasks {
151+ if (_frequencyCounter != self.executeFrequency ) {
152+ ++_frequencyCounter;
153+ return ;
154+ } else {
155+ _frequencyCounter = 1 ;
156+ }
151157 if (_strategy.ybts_empty ) return ;
152158
153159 dispatch_block_t taskBlock = ^{
@@ -161,16 +167,23 @@ - (void)executeTasks {
161167 taskBlock ();
162168 };
163169
164- for (NSUInteger i = 0 ; i < self.numberOfExecuteEachTime ; ++i) {
170+ for (NSUInteger i = 0 ; i < self.executeNumber ; ++i) {
165171 executeBlock ();
166172 }
167173}
168174
169- #pragma mark - getter & setter
175+ #pragma mark - setter
170176
171177- (void )setMaxNumberOfTasks : (NSUInteger )maxNumberOfTasks {
172178 _maxNumberOfTasks = maxNumberOfTasks;
173- _strategy.ybts_maxNumberOfTasks = maxNumberOfTasks;
179+ if ([_strategy respondsToSelector: @selector (setYbts_maxNumberOfTasks: )]) {
180+ _strategy.ybts_maxNumberOfTasks = maxNumberOfTasks;
181+ }
182+ }
183+
184+ - (void )setExecuteFrequency : (NSUInteger )executeFrequency {
185+ _executeFrequency = executeFrequency;
186+ _frequencyCounter = executeFrequency;
174187}
175188
176189@end
0 commit comments