我們已經會了使用一個次執行緒來執行工作,避免主執行緒被中斷掉。現在我們要使用兩個次執行緒來加快我們次執行緒的執行速度,而要用dispatch_group的方式將兩個次執行緒包在一起,如果畫成圖如下所示。
比較:
只有一個次執行緒所執行的時間需要15秒。
有兩個次執行緒所執行的時間僅需要9秒。
【專案開發流程】
這份筆記僅修改開始執行次執行緒動作按鈕所觸發的func,其餘的步驟請參考這裡。
修改按鈕觸發的func:
將以下程式碼替換掉原先在func內的程式,如下所示。
<Swift>
sender.enabled = false
activityIndicator.startAnimating()
var startDate: NSDate = NSDate.date()
<Object-C>
sender.enabled=NO;
[self.activityIndicator startAnimating];
NSDate *startDate = [NSDate date];
將按鈕關閉,不允許只用者使用。設定activityIndicator開始轉動。設立一個變數紀錄現在的時間。
<Swift>
var group: dispatch_group_t = dispatch_group_create()
<Object-C>
dispatch_group_t group = dispatch_group_create();
建立次執行緒的Group。
<Swift>
dispatch_group_async(group, dispatch_get_global_queue(0, 0), {
self.doSomething1()
self.doSomething2()
self.doSomething3()
});
<Object-C>
dispatch_group_async(group, dispatch_get_global_queue(0, 0), ^{
[self doSomething1];
[self doSomething2];
[self doSomething3];
});
加入一個queue至Group內,並執行三個工作。
<Swift>
dispatch_group_async(group, dispatch_get_global_queue(0, 0), {
self.doSomething4()
self.doSomething5()
});
<Object-C>
dispatch_group_async(group, dispatch_get_global_queue(0, 0), ^{
[self doSomething4];
[self doSomething5];
});
加入另一個queue至Group內,並執行兩個工作。
<Swift>
dispatch_group_notify(group, dispatch_get_main_queue(), {
var stopDate: NSDate = NSDate.date()
var overTime: NSTimeInterval = stopDate.timeIntervalSinceDate(startDate)
println("Action time = \(overTime)")
sender.enabled = true
self.activityIndicator.stopAnimating()
});
<Object-C>
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
NSDate *stopDate = [NSDate date];
NSTimeInterval overTime = [stopDate timeIntervalSinceDate:startDate];
NSLog(@"%.f", overTime);
sender.enabled=YES;
[self.activityIndicator stopAnimating];
});
當Group內的queue都工作完畢後會發送通知,我們必須要在跳回去主執行緒執行其他的工作。設立一個stopDate的變數紀錄現在的時間。overTime用來計算從startDate到stopDate的時間。印出所需要的時間。將按鈕開啟,能讓使用者再次使用。令activityIndicator停止運轉。
【專案範例】
func appendContent(text:NSString) {
回覆刪除var str:NSMutableString = NSMutableString(string: self.textView.text)
str.appendString("\(text)\n")
self.textView.text = str
var range = NSMakeRange(str.length - 1, 1)
self.textView.scrollRangeToVisible(range)
}
func gcdSales() {
var queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
var group: dispatch_group_t = dispatch_group_create()
dispatch_group_async(group, queue, {
self.gcdSaleTicketWithName("gcd-1")
})
dispatch_group_async(group, queue, {
self.gcdSaleTicketWithName("gcd-2")
})
// dispatch_group_notify(group, queue, {
// println("票卖完了")
// })
dispatch_group_notify(group, dispatch_get_main_queue(), {
println("票卖完了")
})
dispatch_group_leave(group)
}
func gcdSaleTicketWithName(name:NSString) {
while true {
// 同步锁synchronized要锁的范围,对被抢夺资源修改/读取的代码部分
objc_sync_enter(Ticket.shared)
if Ticket.shared.tickets > 0 {
Ticket.shared.tickets--
var str = "剩余票数:\(Ticket.shared.tickets),线程名称:\(name)"
// 更新界面
dispatch_sync(dispatch_get_main_queue(), {
self.appendContent(str)
})
} else {
break
}
objc_sync_exit(Ticket.shared)
// 模拟线程休眠
if name.isEqualToString("gcd-1") {
NSThread.sleepForTimeInterval(0.2)
} else {
NSThread.sleepForTimeInterval(0.5)
}
}
}
为什么不加这一句“dispatch_group_leave(group)”的时候,我的demo不会执行notify里的代码,而你的demo中会执行notify中的代码
而你的demo中却可以执行
可否將專案寄給我,比較方便抓出問題點
刪除