多線程
注意:iOS關於UI的刷新和添加必須在主線程中操作!
pthread的創建方法:
pthread_t pthread;
//第一個參數 線程指針
//第二個參數 線程的一些屬性
//第三個參數 函數指針 用於執行方法
//第四個參數 線程中的傳值
pthread_create(&pthread, NULL, run, NULL);
當應用程序剛運行的時候, 系統會自動為我們開放一個線程,該線程為主線程.
子線程是程序員用代碼手動開啟的線程,它存在的意義是為了執行耗時操作的任務.
一、NSThread的創建方法:
1.
NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(haoshicaozuo) object:@"123"];
thread.name = @"123";
//開啟線程
[thread start];
2.快捷創建
[NSThread detachNewThreadSelector:@selector(haoshicaozuo) toTarget:self withObject:@"456"]; [self performSelectorInBackground:@selector(haoshicaozuo) withObject:@"123"];
下面一行代碼指的是睡眠時間, 根據特定需求修改時長.
[NSThread sleepForTimeInterval:0.5];
二、NSOperation
NSOperation是一個抽象類,我們一般不直接使用它,而是使用它的子類NSInvocationOperation和NSBlockOperation,如果他們單獨使用都是在主線程執行,只有和隊列放在一起使用時在子線程執行.
NSInvocationOperation *operation1 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(operationAction1) object:nil];
// [operation1 start];
NSInvocationOperation *operation2 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(operationAction2) object:nil];
NSBlockOperation *operation3 = [NSBlockOperation blockOperationWithBlock:^{
for (int i = 20; i < 30; i++) {
NSLog(@"%d", i);
}
}];
//加入到隊列
//mainQueue代表著主隊列
// NSOperationQueue *queue = [NSOperationQueue mainQueue];
//如果是alloc init 那就代表著其他對列
//先加的先執行,後加的後執行, 但是執行的時間不一定, 可能後執行的比先執行的先執行完
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[queue addOperation:operation1];
[queue addOperation:operation2];
[queue addOperation:operation3];
三、GCD
異步: 不在一個線程執行
同步: 在同一個線程執行
串行: 串在一起執行
並行: 一起執行
同步 + 主隊列 :所有通過GCD提交到主隊列的任務必須是異步的, 否則會造成死鎖
異步 + 主隊列 : 不開辟線程, 就在主線程執行 (主隊列就是串行的)
同步 + 串行對列: 不具備開啟線程的能力, 在當前線程完成任務
異步 + 串行 :具備開啟線程的能力, 但是任務是串行的,執行完一個才會去執行下一個
同步 + 並行隊列 : 不具備開啟線程的能力,並發的功能也就沒用了
並行隊列的兩種創建方式:
dispatch_queue_t queue = dispatch_queue_create("sb.2b.com", DISPATCH_QUEUE_CONCURRENT);
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
異步 + 並發隊列
三(一):GCD網絡請求:
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
dispatch_queue_t queue = dispatch_queue_create("aaa", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue, ^{
NSURL *url = [NSURL URLWithString:@"https://ss0.bdstatic.com/94oJfD_bAAcT8t7mm9GUKT-xh_/timg?image&quality=100&size=b4000_4000&sec=1464140268&di=6b6b2e3ea5da34b7da1e02fd28c7acd2&src=http://pic36.nipic.com/20131115/12106414_153522431000_2.jpg"];
NSData *data = [NSData dataWithContentsOfURL:url];
dispatch_sync(dispatch_get_main_queue(), ^{
self.myImageView.image = [UIImage imageWithData:data];
});
});
}
三(二):GCD函數的使用:
延遲執行block
void dispatch_after(dispatch_time_t when, dispatch_queue_t queue, dispatch_block_t block);
重復執行block,需要注意的是這個方法是同步返回,也就是說等到所有block執行完畢才返回,如需異步返回則嵌套在dispatch_async中來使用。多個block的運行是否並發或串行執行也依賴queue的是否並發或串行。
void dispatch_apply(size_t iterations, dispatch_queue_t queue, void (^block)(size_t));