串行隊列infact確保在第二個塊執行之前,添加到隊列中的第一個塊執行完成。
-(void)testSerialQueue
{
dispatch_queue_t serialQueue = dispatch_queue_create("com.serial.queue", DISPATCH_QUEUE_SERIAL);
dispatch_async(serialQueue, ^{
[self countTo100];
});
dispatch_async(serialQueue, ^{
[self countFrom200To400];
});
dispatch_async(serialQueue, ^{
[self countFrom400To500];
});
}
- (void)countTo100
{
for (int i = 0; i < 100; i++) {
NSLog(@"%d", i);
}
}
- (void)countFrom200To400
{
for (int i = 200; i < 400; i++) {
NSLog(@"%d", i);
}
}
- (void)countFrom400To500
{
for (int i = 400; i < 500; i++) {
NSLog(@"%d", i);
}
}
如果你看看日誌從上面它將從0連續打印.. 100先200 ... 400和400 ... 500
現在,考慮下面的代碼片段,在那裏你執行每個方法併發塊內等,
-(void)testSerialQueue
{
dispatch_queue_t serialQueue = dispatch_queue_create("com.serial.queue", DISPATCH_QUEUE_SERIAL);
dispatch_async(serialQueue, ^{
[self countTo100];
});
dispatch_async(serialQueue, ^{
[self countFrom200To400];
});
dispatch_async(serialQueue, ^{
[self countFrom400To500];
});
}
- (void)countTo100
{
dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(concurrentQueue, ^{
for (int i = 0; i < 100; i++) {
NSLog(@"%d", i);
}
});
}
- (void)countFrom200To400
{
dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(concurrentQueue, ^{
for (int i = 200; i < 400; i++) {
NSLog(@"%d", i);
}
});
}
- (void)countFrom400To500
{
dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(concurrentQueue, ^{
for (int i = 400; i < 500; i++) {
NSLog(@"%d", i);
}
});
}
在這裏,你添加的所有串行隊列中,但本身的併發塊運行方法中的方法。所以,在這種情況下結果是隨機的。你也可以序列,使用dispatch_group這樣,
-(void)testSerialQueue
{
dispatch_queue_t serialQueue = dispatch_queue_create("com.serial.queue", DISPATCH_QUEUE_SERIAL);
self.group = dispatch_group_create();
dispatch_async(serialQueue, ^{
[self countTo100];
});
dispatch_async(serialQueue, ^{
[self countFrom200To400];
});
dispatch_async(serialQueue, ^{
[self countFrom400To500];
});
}
- (void)countTo100
{
dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_enter(self.group);
dispatch_async(concurrentQueue, ^{
for (int i = 0; i < 100; i++) {
NSLog(@"%d", i);
}
dispatch_group_leave(self.group);
});
dispatch_group_wait(self.group, DISPATCH_TIME_FOREVER);
}
- (void)countFrom200To400
{
dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_enter(self.group);
dispatch_async(concurrentQueue, ^{
for (int i = 200; i < 400; i++) {
NSLog(@"%d", i);
}
dispatch_group_leave(self.group);
});
dispatch_group_wait(self.group, DISPATCH_TIME_FOREVER);
}
- (void)countFrom400To500
{
dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_enter(self.group);
dispatch_async(concurrentQueue, ^{
for (int i = 400; i < 500; i++) {
NSLog(@"%d", i);
}
dispatch_group_leave(self.group);
});
dispatch_group_wait(self.group, DISPATCH_TIME_FOREVER);
}
在這裏,你將再次看到它打印記錄有序。因此,dispatch_group用於序列化併發操作。您可能更願意在此時刪除serialQueue中的dispatch_async。
現在,操作隊列,讓我們看看簡單的例子,
-(void)testSerialQueue
{
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
queue.maxConcurrentOperationCount = 1;
NSBlockOperation *operation1 = [[NSBlockOperation alloc] init];
NSBlockOperation *operation2 = [[NSBlockOperation alloc] init];
NSBlockOperation *operation3 = [[NSBlockOperation alloc] init];
[operation1 addExecutionBlock:^{
[self countTo100];
}];
[operation2 addExecutionBlock:^{
[self countFrom200To400];
}];
[operation3 addExecutionBlock:^{
[self countFrom400To500];
}];
}
- (void)countTo100
{
for (int i = 0; i < 100; i++) {
NSLog(@"%d", i);
}
}
- (void)countFrom200To400
{
for (int i = 200; i < 400; i++) {
NSLog(@"%d", i);
}
}
- (void)countFrom400To500
{
for (int i = 400; i < 500; i++) {
NSLog(@"%d", i);
}
}
計數方法是加入NSOperationQueue與maxConcurrentOperation爲「1」現在更像一個串行隊列。每種方法都不會產生其他一些隊列,所以計數在同一個串行隊列上執行。所以,他們都打印有序。
現在,讓我們看一個模擬您的案例的例子。
-(void)testSerialQueue
{
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
queue.maxConcurrentOperationCount = 1;
NSBlockOperation *operation1 = [[NSBlockOperation alloc] init];
NSBlockOperation *operation2 = [[NSBlockOperation alloc] init];
NSBlockOperation *operation3 = [[NSBlockOperation alloc] init];
[operation1 addExecutionBlock:^{
[self countTo100];
}];
[operation2 addExecutionBlock:^{
[self countFrom200To400];
}];
[operation3 addExecutionBlock:^{
[self countFrom400To500];
}];
}
- (void)countTo100
{
dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(concurrentQueue, ^{
for (int i = 0; i < 100; i++) {
NSLog(@"%d", i);
}
});
}
- (void)countFrom200To400
{
dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(concurrentQueue, ^{
for (int i = 200; i < 400; i++) {
NSLog(@"%d", i);
}
});
}
- (void)countFrom400To500
{
dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(concurrentQueue, ^{
for (int i = 400; i < 500; i++) {
NSLog(@"%d", i);
}
});
}
在這種使用情況下,您可以添加操作到NSOperationQueue(即串行隊列),但再次,在一些其他併發隊列運行單個方法。所以,執行順序是非常隨機的。現在,您可以像使用串行隊列一樣使用dispatch_group解決此問題。
-(void)testSerialQueue
{
self.group = dispatch_group_create();
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
queue.maxConcurrentOperationCount = 1;
NSBlockOperation *operation1 = [[NSBlockOperation alloc] init];
NSBlockOperation *operation2 = [[NSBlockOperation alloc] init];
NSBlockOperation *operation3 = [[NSBlockOperation alloc] init];
[operation1 addExecutionBlock:^{
[self countTo100];
}];
[operation2 addExecutionBlock:^{
[self countFrom200To400];
}];
[operation3 addExecutionBlock:^{
[self countFrom400To500];
}];
}
- (void)countTo100
{
dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_enter(self.group);
dispatch_async(concurrentQueue, ^{
for (int i = 0; i < 100; i++) {
NSLog(@"%d", i);
}
dispatch_group_leave(self.group);
});
dispatch_group_wait(self.group, DISPATCH_TIME_FOREVER);
}
- (void)countFrom200To400
{
dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_enter(self.group);
dispatch_async(concurrentQueue, ^{
for (int i = 200; i < 400; i++) {
NSLog(@"%d", i);
}
dispatch_group_leave(self.group);
});
dispatch_group_wait(self.group, DISPATCH_TIME_FOREVER);
}
- (void)countFrom400To500
{
dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_enter(self.group);
dispatch_async(concurrentQueue, ^{
for (int i = 400; i < 500; i++) {
NSLog(@"%d", i);
}
dispatch_group_leave(self.group);
});
dispatch_group_wait(self.group, DISPATCH_TIME_FOREVER);
}
現在,你會看到計數再次有序。這是因爲dispatch_group等待每個異步任務完成。
爲您的特定的使用情況,您可以使用循環調用一些方法,像這樣創造NSInvocationOperation,
-(void)testSerialQueue
{
self.group = dispatch_group_create();
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
queue.maxConcurrentOperationCount = 1;
NSArray *selectors = @[@"countTo100", @"countFrom200To400", @"countFrom400To500"];
for (NSString *selector in selectors) {
NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self
selector:NSSelectorFromString(selector)
object:nil];
[queue addOperation:operation];
}
}
- (void)countTo100
{
dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_enter(self.group);
dispatch_async(concurrentQueue, ^{
for (int i = 0; i < 100; i++) {
NSLog(@"%d", i);
}
dispatch_group_leave(self.group);
});
dispatch_group_wait(self.group, DISPATCH_TIME_FOREVER);
}
- (void)countFrom200To400
{
dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_enter(self.group);
dispatch_async(concurrentQueue, ^{
for (int i = 200; i < 400; i++) {
NSLog(@"%d", i);
}
dispatch_group_leave(self.group);
});
dispatch_group_wait(self.group, DISPATCH_TIME_FOREVER);
}
- (void)countFrom400To500
{
dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_enter(self.group);
dispatch_async(concurrentQueue, ^{
for (int i = 400; i < 500; i++) {
NSLog(@"%d", i);
}
dispatch_group_leave(self.group);
});
dispatch_group_wait(self.group, DISPATCH_TIME_FOREVER);
}