//創建分線程 讓耗時的操作在分線程里執行 跟主線程是異步的
[self performSelectorInBackground:@selector(calculateSum) withObject:nil];
二、同過創建分線程
1、NSThread
NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(calculateSum) object:nil];
//? ? 通過對象方法初始化的thread必須要 start
[thread start];
2、不需要手動開啟
[NSThread detachNewThreadSelector:@selector(calculateSum) toTarget:self withObject:nil];
3、線程安全
//線程的安全 多個線程同時去訪問一個資源的時候 要去保證資源的合理分配 不能讓資源產生混亂
//我們要給資源加上鎖
//對于同一個資源來說? 同一時間內 只能有一個人(線程)去訪問
//所以我們要上鎖
NSLock *lock = [[NSLock alloc] init];
NSThread *thread1 = [[NSThread alloc] initWithTarget:self selector:@selector(buyTickets:) object:lock];
//加鎖 不讓其他人(線程來訪問)
[sender lock];
//訪問完之后打開鎖 讓其他人(線程)可以繼續訪問
[sender unlock];
三、隊列
1、初始化線程
//初始化NSInvocationOperation 它是operation的子類
NSInvocationOperation *op1 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(op1Handle) object:nil];
NSInvocationOperation *op2 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(op2Handle) object:nil];
NSInvocationOperation *op3 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(op3Handle) object:nil];
2、隊列的創建
//創建操作隊列 只有用queue(隊列 系統才會自動的幫我們創建分線程)
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
3、設置隊列中的線程是否串行或者并行
//設置同一時間內 最大的并行個數? 誰先添加 誰執行
//當設置1的時候 三個線程是串行
//當設置最大的時候 也就是3的時候 并行 同時執行完 但是打印的順序不一定
[queue setMaxConcurrentOperationCount:1];
4、設置隊列的優先級
//設置在隊列里邊的優先級
[op3 setQueuePriority:NSOperationQueuePriorityVeryHigh];
5、控制優先級
//依賴 可以精準的控制誰先執行
[op1 addDependency:op3];
[op2 addDependency:op3];
6、
//把操作放到隊列里
[queue addOperation:op1];
[queue addOperation:op2];
[queue addOperation:op3];
7、通過block來創建線程
NSBlockOperation *blockOperation1 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"blockOperation11111111----->%d",[NSThread isMainThread]);
}];
[queue addOperation:blockOperation1];
//總結:不管用哪一種,把他們加到隊列中,系統都會自動幫我們創建分線程
//把當前分線程推出掉
[NSThread exit];
//讓當前線程休眠3秒
[NSThread sleepForTimeInterval:3];
sleep(3);
三、GCD(串行)
1、開辟主線程
//主線程隊列
dispatch_queue_t quque= dispatch_get_main_queue();
dispatch_sync(quque, ^{
NSLog(@"這是我在主線程隊列創建了一個同步任務");
});
//分線程創建
dispatch_async(quque, ^{
NSLog(@"我是第一個任務,當前線程%@ 是否主線程-->%d",[NSThread currentThread],[NSThread isMainThread]);
});
2、DISPATCH_QUEUE_SERIAL
//第二種? DISPATCH_QUEUE_SERIAL通過create去創建一個串行隊列 調用 異步 只會創建一個分線程
dispatch_queue_t quque = dispatch_queue_create("XXX.YYY.ZZZ", DISPATCH_QUEUE_SERIAL);
//分線程創建
dispatch_async(quque, ^{
NSLog(@"我是第一個任務,當前線程%@ 是否主線程-->%d",[NSThread currentThread],[NSThreadisMainThread]);
});
四、GCD(并行)
//并行隊列 添加異步任務 任務會并行執行(也就是一起跑,同時結束)系統會去幫我們自動創建分線程且是多個
//第一個參數 隊列的優先級 第二個參數 留給未來的
//第一種
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
//第二種創建并行隊列
dispatch_queue_t quque = dispatch_queue_create("XXX.YYY.ZZZ", DISPATCH_QUEUE_CONCURRENT);
五、延遲操作
//不管在那個隊列里都會延遲
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), queue, ^{
NSLog(@"在主線程延遲5秒");
});
六、組隊列
//聲明一個group
dispatch_group_t group = dispatch_group_create();
//聲明一個全局(并行)隊列
dispatch_queue_t queue1 = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
__block NSString *str;
dispatch_group_async(group, queue1, ^{
NSLog(@"ismain-->%d",[NSThread isMainThread]);
NSLog(@"我是group中的第一個隊列");
str = @"kkk";
});
__block NSString *str2;
dispatch_group_async(group, queue1, ^{
NSLog(@"我是group中的第二個隊列");
str2 = @"在2班";
});
dispatch_group_notify(group, queue1, ^{
NSLog(@"我是group里的總結");
NSString *str3 = [NSString stringWithFormat:@"%@%@",str,str2];
NSLog(@"total__%@",str3);
});
七、路障
//注意:這里只能用create創建并行隊列 路障永遠是卡在中間的
dispatch_queue_t queue = dispatch_queue_create("xxxx", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue, ^{
NSLog(@"我是第一個任務,當前線程%@ 是否主線程—>%d",[NSThread currentThread],[NSThread isMainThread]);
});
dispatch_async(queue, ^{
NSLog(@"我是第二個任務,當前線程%@ 是否主線程—>%d",[NSThread currentThread],[NSThread isMainThread]);
});
//路障創建
dispatch_barrier_async(queue, ^{
NSLog(@"我是路障,后邊等一會兒");
});
dispatch_async(queue, ^{
NSLog(@"我是第三個任務,當前線程%@ 是否主線程—>%d",[NSThread currentThread],[NSThread isMainThread]);
});
八、主分線程跳轉
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
//并行隊列的異步,去加載圖片數據
dispatch_async(queue, ^{
NSLog(@"ismain—>%d",[NSThread isMainThread]);
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://desk.3987.com/uploadfile/2014/0409/20140409101946485.jpg"]];
if (data) {
//當有數據之后? 我們回到主線程去給image加載圖片
dispatch_async(dispatch_get_main_queue(), ^{
self.imageView.image = [UIImage imageWithData:data];
NSLog(@"是不是主線程—>%d",[NSThread isMainThread]);
});
}
});