新開多線程:
(普通)
// GCD 是基于隊列的 多線程實現(xiàn)方式
// 隊列的類型
// 1.并行: 多個任務同時執(zhí)行 Concurrent
// 2.串行: 依次執(zhí)行任務(同一事件只執(zhí)行一個任務) Serial
// 自己創(chuàng)建一個隊列
// 參數(shù)1:給隊列起個名字
// 參數(shù)2:選擇隊列的類型 DISPATCH_QUEUE_CONCURRENT(串行)
dispatch_queue_t queue = dispatch_queue_create("test", DISPATCH_QUEUE_CONCURRENT);
// 使用隊列
// 參數(shù)1: 在哪個隊列執(zhí)行代碼
// 參數(shù)2: 要執(zhí)行的代碼
dispatch_async(queue, ^{
[self downLoadImage]; //回調(diào)
});
(高級用法)
// 系統(tǒng)定義了5個隊列
// 1. 一個串行隊列 主隊列作用 : 管理主線程的相關(guān)事務
// 獲得主隊列
dispatch_queue_t mainQueue = dispatch_get_main_queue();
// 在主隊列執(zhí)行任務
// dispatch_async(mainQueue, ^{
// [self btnUpClicked:nil];
// });
// 2. 4個并行隊列 (并行隊列)
// 參數(shù)1: 選擇隊列的優(yōu)先級
// 參數(shù)2: 給未來使用 一般填0
dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
// dispatch_async(globalQueue, ^{
// [self btnUpClicked:nil];
// });
// 高端使用
// 1.全局隊列獲取數(shù)據(jù) 回到主隊列將數(shù)據(jù)加載到視圖上
// dispatch_async(globalQueue, ^{
//
// // 全局隊列(子線程)獲取數(shù)據(jù)
// NSString *str = @"htt://www.baidu.com";
// NSURL *url = [NSURL URLWithString:str];
//
// NSData *data = [NSData dataWithContentsOfURL:url];
// UIImage *image = [UIImage imageWithData:data];
//
// // 返回主線程 加載UI/更新UI
// dispatch_async(mainQueue, ^{
//
// UIImageView *imageView = [[UIImageView alloc] init];
// // 給視圖賦值
// imageView.image = image;
//
// });
// });
// 2.一段代碼只執(zhí)行依次
// 大部分的時候 都在單例方法中使用
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
NSLog(@"只執(zhí)行依次");
});
// 3.一段代碼執(zhí)行多次 (全局隊列有效)
// 參數(shù)1: 執(zhí)行多少次
// 參數(shù)2: 在哪個隊列有效
// 參數(shù)3: 要執(zhí)行的內(nèi)容
dispatch_apply(4, globalQueue, ^(size_t a) {
NSLog(@"%zu", a);
});
// 4.定時
// 參數(shù)1: 間隔幾秒
// 參數(shù)2: 執(zhí)行的內(nèi)容
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(44 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSLog(@"=====");
});
學習
#pragma mark -- 開辟線程
//一盐数、NSObject 隱式開辟線程
//開辟后臺線程 執(zhí)行某方法
// [self performSelectorInBackground:@selector(loadingImageWithUrlString:) withObject:IMAGE_URL];
//會到主線程中做某事
// [self performSelectorOnMainThread:<#(nonnull SEL)#> withObject:<#(nullable id)#> waitUntilDone:<#(BOOL)#>]
//二催享、 NSThread 線程類 對pthread的一種封裝
// [NSThread detachNewThreadSelector:@selector(loadingImageWithUrlString:) toTarget:self withObject:IMAGE_URL];
//對象方法 需要手動管理
// NSThread *thread = [[NSThread alloc]initWithTarget:self selector:@selector(loadingImageWithUrlString:) object:IMAGE_URL];
// [thread start];/**< 手動開啟 */
//三、NSOperation 抽象類 需要用子類初始化诬乞,需要加入到線程對壘中進行管理
NSOperationQueue *queue = [[NSOperationQueue alloc]init];//創(chuàng)建多線程隊列
//NSInvocationOperation 是NSOperation的子類
NSInvocationOperation *invocationOperation = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(loadingImageWithUrlString:) object:IMAGE_URL];
[invocationOperation setCompletionBlock:^{
//更新UI
}];
//加入隊列
[queue addOperation:invocationOperation];
//NSBlockOperation
NSBlockOperation *blockOpertion = [NSBlockOperation blockOperationWithBlock:^{
//做線程里面的事俊抵,耗時操作
[self loadingImageWithUrlString:IMAGE_URL];
}];
[blockOpertion setCompletionBlock:^{
//更新UI
}];
[queue addOperation:blockOpertion];
//簡寫 NSBlockOperation
[queue addOperationWithBlock:^{
//做線程里面的事慢叨,耗時操作
}];
#pragma mark -- GCD
//四、GCD(中央調(diào)度)優(yōu)勢:自動選取CPU內(nèi)核务蝠,線程自己管理
//并發(fā):多個任務同時執(zhí)行(在異步下才有效果)
//串行:任務一個一個執(zhí)行
//同步:在當前線程中執(zhí)行拍谐,不具有開辟線程的功能
//異步:開辟一個線程去執(zhí)行任務,具有開辟線程的能力
//任務(bolck) - 隊列(queue)
//dispatch_get_main_queue() 特殊的串行隊列馏段,起任務只在主線程中執(zhí)行
dispatch_async(dispatch_get_main_queue(), ^{
//任務
});
//串行隊列
// dispatch_queue_t myQueue = dispatch_queue_create("name",DISPATCH_QUEUE_SERIAL);
//并發(fā)隊列
dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(globalQueue, ^{
//執(zhí)行任務
//耗時操作
dispatch_async(dispatch_get_main_queue(), ^{
//更新UI
});
});
#pragma mark -- 隊列組
//隊列組轩拨,同時執(zhí)行多個耗時操作
//創(chuàng)建隊列組
dispatch_group_t groupQueue = dispatch_group_create();
dispatch_group_async(groupQueue, globalQueue, ^{
//耗時操作一
});
dispatch_group_async(groupQueue, globalQueue, ^{
//耗時操作二
});
dispatch_group_async(groupQueue, dispatch_get_main_queue(), ^{
//更新UI
});
}
- (void)loadingImageWithUrlString:(NSString *)string{
//從網(wǎng)上獲取圖片
NSURL *url = [NSURL URLWithString:string];
NSData *data = [NSData dataWithContentsOfURL:url];
//刷新界面 放入主線程中執(zhí)行
dispatch_async(dispatch_get_main_queue(), ^{
self.contentImageView.image = [UIImage imageWithData:data];
});
self.loadImageView.hidden = YES;
}
#pragma mark -- 線程安全
- (void)openThread{
//創(chuàng)建兩個線程同時進行一個操作
NSThread *thread1 = [[NSThread alloc]initWithTarget:self selector:@selector(countChanged) object:nil];
thread1.name = @"thread1";
[thread1 start];
NSThread *thread2 = [[NSThread alloc]initWithTarget:self selector:@selector(countChanged) object:nil];
thread2.name = @"thread2";
[thread2 start];
}
- (void)countChanged{
static int count = 20;
// //創(chuàng)建一個死循環(huán)
// while (1) {
// //添加線程鎖
// [self.lock lock];
//
// NSLog(@"%@ - %d",[NSThread currentThread],count);
// count --;
// if (count < 0) {
// break;
// }
// //解鎖
// [self.lock unlock];
// }
@synchronized(self) {
//具有線程安全的
while (1) {
NSLog(@"%@ - %d",[NSThread currentThread],count);
count --;
if (count < 0) {
break;
}
}
}
}