/**
* 獲取網絡數據、處理大批量數據、使用到一些比較耗時的算法時,需要使用子線程處理
*/
// 開啓一個子線程,把for循環交給子線程完成(每觸發一次就創建一個線程)
NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(cycle) object:nil];
// 啓動子線程(手動啓動)
[thread start];
[thread release];
// 啓動子線程,(自動啓動)
[NSThread detachNewThreadSelector:@selector(cycle) toTarget:self withObject:nil];
[NSThread detachNewThreadSelector:@selector(downloadImage) toTarget:self withObject:nil];
// 自動啓動子線程 (等同上邊方法)
[self performSelectorInBackground:@selector(downloadImage) withObject:nil];
// NSOperationQueue
// 1.NSInvocationOperation
NSInvocationOperation *invocationOperation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(test:) object:@"參數"];
// [invocationOperation start];
// [invocationOperation release];
// 2.NSBlockOperation
NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"blockOperaction");
}];
// [blockOperation start];
// 3.NSOperationQueue(用來存放任務的隊列)
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
// 添加依賴關係,當一個任務執行完後,另一個再執行(設置當block執行完成後再執行invocationoperation)
[invocationOperation addDependency:blockOperation];
// 設置最大可同時執行的任務數量
// queue.maxConcurrentOperationCount = 1;
// 添加任務到隊列中(將任務添加到隊列中後會自動執行,不必手動start)
[queue addOperation:invocationOperation];
[queue addOperation:blockOperation];
[invocationOperation release];
4、使用GCD創建子線程
/**
* 1.GCD: 分派隊列 ,FIFO
* 2.串行隊列:前一個任務執行完畢,下一個任務纔開始執行
* 3.並行隊列:任務在派發的過程中是有序的,但是不用等待前一個任務完成,下一個任務就可以開始
* 4.GCD中的隊列分爲三種,主隊列,全局隊列,自定義隊列
*/
// 1.使用主隊列實現任務的派發,串行。主隊列分派的任務,永遠在主線程中
dispatch_queue_t mainQueue = dispatch_get_main_queue();
// 1.1 添加任務
dispatch_async(mainQueue, ^{
NSLog(@"第一個任務,當前線程是:%@",[NSThread currentThread]);
});
dispatch_async(mainQueue, ^{
NSLog(@"第二個任務,當前線程是:%@",[NSThread currentThread]);
});
dispatch_async(mainQueue, ^{
NSLog(@"第三個任務,當前線程是:%@",[NSThread currentThread]);
});
dispatch_async(mainQueue, ^{
NSLog(@"第四個任務,當前線程是:%@",[NSThread currentThread]);
});
// 2.自己創建隊列,串行,任務會分派在子線程中
dispatch_queue_t myQueue = dispatch_queue_create("com.lanou.myqueue", DISPATCH_QUEUE_SERIAL);//DISPATCH_QUEUE_SERIAL:串行
// 2.1添加任務
dispatch_async(myQueue, ^{
NSLog(@"第一個任務,當前線程是:%@",[NSThread currentThread]);
});
dispatch_async(myQueue, ^{
NSLog(@"第二個任務,當前線程是:%@",[NSThread currentThread]);
});
dispatch_async(myQueue, ^{
NSLog(@"第三個任務,當前線程是:%@",[NSThread currentThread]);
});
dispatch_async(myQueue, ^{
NSLog(@"第四個任務,當前線程是:%@",[NSThread currentThread]);
});
// 3.自定義隊列,並行
dispatch_queue_t myQueue = dispatch_queue_create("com.lanou.myQueue", DISPATCH_QUEUE_CONCURRENT);//DISPATCH_QUEUE_CONCURRENT:並行
dispatch_async(myQueue, ^{
NSLog(@"第一個任務,當前線程是:%@",[NSThread currentThread]);
});
dispatch_async(myQueue, ^{
NSLog(@"第二個任務,當前線程是:%@",[NSThread currentThread]);
});
dispatch_async(myQueue, ^{
NSLog(@"第三個任務,當前線程是:%@",[NSThread currentThread]);
});
dispatch_async(myQueue, ^{
NSLog(@"第四個任務,當前線程是:%@",[NSThread currentThread]);
});
// 4.利用系統創建並行隊列
dispatch_queue_t queue2 = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);//DISPATCH_QUEUE_PRIORITY_DEFAULT 優先級默認
dispatch_async(queue2, ^{
NSLog(@"第一個任務,當前線程是:%@",[NSThread currentThread]);
});
dispatch_async(queue2, ^{
NSLog(@"第二個任務,當前線程是:%@",[NSThread currentThread]);
});
dispatch_async(queue2, ^{
NSLog(@"第三個任務,當前線程是:%@",[NSThread currentThread]);
});
dispatch_async(queue2, ^{
NSLog(@"第四個任務,當前線程是:%@",[NSThread currentThread]);
});
// 5.實例:獲取網絡圖片數據
__block ViewController *vc = self;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// 5.1 獲取網絡圖片數據
NSURL *url = [NSURL URLWithString:@"http://pic1.win4000.com/wallpaper/6/53bfb7f60d991.jpg"];
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *image = [UIImage imageWithData:data];
// 5.2在主線程中顯示圖片數據
dispatch_async(dispatch_get_main_queue(), ^{
[vc showImage:image];
});
});
/**
* GCD提供的福利
*/
for (int i = 0; i < 10; i++) {
static dispatch_once_t onceToken; //讓代碼只走一次dispatch_once_GCD.....
dispatch_once(&onceToken, ^{
NSLog(@"haha");
});
}
for (int i = 0; i < 10; i++) { // 代碼延遲五秒執行:dispatch_after_GCD......
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSLog(@"讓代碼延遲五秒執行");
});
}
// 指定代碼執行若干次
dispatch_apply(4, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(size_t t) {
NSLog(@"指定代碼執行若干次");
});
/**
* 1.脫離線程:當線程內部代碼執行完畢後,線程自動關閉,稱爲脫離線程。例如:NSThread,Background
* 2.非脫離線程:當線程內部代碼執行完畢後,線程不關閉,等待着繼續被使用,稱爲非脫離線程。例如:NSOperation
*/
// 5.2在主線程中顯示圖片數據
dispatch_async(dispatch_get_main_queue(), ^{
[vc showImage:image];
});
方法二:
// 5.回到主線程顯示圖片
[self performSelectorOnMainThread:@selector(showImage:) withObject:image waitUntilDone:YES];