iOS中的多線程一般使用場景

在IOS開發中為提高程序的運行效率會將比較耗時的操作放在子線程中執行,iOS系統進程默認啟動一個主線程,用來響應用戶的手勢操作以及UI刷新,因此主線程又叫做UI線程。
前面的Blog說明了NSThread以及GCD處理并發線程以及線程安全(線程鎖@synchronized(){}),線程通信(從子線程向主線程傳遞值,刷新界面),接下來討論線程的延遲與執行的單一化(唯一執行一次)。
1.延遲
(1)最簡單粗暴的方法是對線程本身執行掛起操作
[NSThread sleepForTimeInterval:]
另外使用隱式創建開啟線程的方法
self performSelector:withObject:afterDelay:
(2)使用GCD處理延遲操作(線程,任務)
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(<#delayInSeconds#> * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
<#code to be executed after a specified delay#>
});
2.只執行一次
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
<#code to be executed once#>
});
3.為了方便管理任務隊列中的任務,GCD特用分組的方式來管理
dispatch_group_t group = dispatch_group_create();
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_async(group, queue, ^{
});
dispatch_group_notify(group, queue, ^{});
4.NSOperation與NSOperationQueue
為了對線程的操作更加的面向對象,APPLE對GCD進行了封裝,特將任務—->封裝成NSOperation
隊列——>封裝成NSOperationQueue
(1)NSOperation有兩個子類NSInvocationOperation以及NSBlockOperation
NSInvocationOperation的創建方法如下:
// 創建隊列
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
// 創建操作
NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(download) object:nil];
// operation直接調用start,是同步執行(在當前線程執行操作)
// [operation start];

// 添加操作到隊列中,會自動異步執行
[queue addOperation:operation];

(2)NSBlockOperation的創建方法:
NSBlockOperation *operation1 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@”—下載圖片—-11—%@”, [NSThread currentThread]);
}];

[operation1 addExecutionBlock:^{NSLog(@"---下載圖片----12---%@", [NSThread currentThread]);
}];NSBlockOperation *operation2 = [NSBlockOperation blockOperationWithBlock:^{NSLog(@"---下載圖片----2---%@", [NSThread currentThread]);
}];NSBlockOperation *operation3 = [NSBlockOperation blockOperationWithBlock:^{NSLog(@"---下載圖片----3---%@", [NSThread currentThread]);
}];NSBlockOperation *operation4 = [NSBlockOperation blockOperationWithBlock:^{NSLog(@"---下載圖片----4---%@", [NSThread currentThread]);
}];// 1.創建隊列
NSOperationQueue *queue = [[NSOperationQueue alloc] init];// 主隊列

// NSOperationQueue *queue = [NSOperationQueue mainQueue];

// 2.添加操作到隊列中(自動異步執行)
[queue addOperation:operation1];
[queue addOperation:operation2];
[queue addOperation:operation3];
[queue addOperation:operation4];

其中NSOperation類可以添加執行代碼塊:addExecutionBlock
【NSOperationQueue mainQueue】是獲取主隊列,其實底層相當于dispatch_get_mainQueue()

NSBlockOperation *operation = [[NSBlockOperation alloc] init];[operation addExecutionBlock:^{NSLog(@"---下載圖片----1---%@", [NSThread currentThread]);
}];[operation addExecutionBlock:^{NSLog(@"---下載圖片----2---%@", [NSThread currentThread]);
}];[operation addExecutionBlock:^{NSLog(@"---下載圖片----3---%@", [NSThread currentThread]);
}];[operation start];// 任務數量 > 1,才會開始異步執行

5.線程的通信
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[queue addOperationWithBlock:^{
// 1.異步下載圖片
NSURL *url = [NSURL URLWithString:@”http://d.hiphotos.baidu.com/image/pic/item/37d3d539b6003af3290eaf5d362ac65c1038b652.jpg“];
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *image = [UIImage imageWithData:data];

    // 2.回到主線程,顯示圖片

// [self performSelectorOnMainThread:<#(SEL)#> withObject:<#(id)#> waitUntilDone:<#(BOOL)#>];
// dispatch_async(dispatch_get_main_queue(), ^{
//
// });
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
self.imageView.image = image;
}];
}];
控制Operation之間的運行順序可以通過添加依賴來實現
- (void)dependency
{
/**
假設有A、B、C三個操作,要求:
1. 3個操作都異步執行
2. 操作C依賴于操作B
3. 操作B依賴于操作A
*/

// 1.創建一個隊列(非主隊列)
NSOperationQueue *queue = [[NSOperationQueue alloc] init];// 2.創建3個操作
NSBlockOperation *operationA = [NSBlockOperation blockOperationWithBlock:^{NSLog(@"A1---%@", [NSThread currentThread]);
}];
//    [operationA addExecutionBlock:^{
//        NSLog(@"A2---%@", [NSThread currentThread]);
//    }];
//
//    [operationA setCompletionBlock:^{
//        NSLog(@"AAAAA---%@", [NSThread currentThread]);
//    }];NSBlockOperation *operationB = [NSBlockOperation blockOperationWithBlock:^{NSLog(@"B---%@", [NSThread currentThread]);
}];
NSBlockOperation *operationC = [NSBlockOperation blockOperationWithBlock:^{NSLog(@"C---%@", [NSThread currentThread]);
}];// 設置依賴
[operationB addDependency:operationA];
[operationC addDependency:operationB];// 3.添加操作到隊列中(自動異步執行任務)
[queue addOperation:operationC];
[queue addOperation:operationA];
[queue addOperation:operationB];

}

為了達到優化app性能的需求,有時候是需要控制并發線程的數目以及隊列中的線程的運行狀態
- (void)maxCount
{
// 1.創建一個隊列(非主隊列)
NSOperationQueue *queue = [[NSOperationQueue alloc] init];

// 2.設置最大并發(最多同時并發執行3個任務)
queue.maxConcurrentOperationCount = 3;// 3.添加操作到隊列中(自動異步執行任務,并發)
NSBlockOperation *operation1 = [NSBlockOperation blockOperationWithBlock:^{NSLog(@"下載圖片1---%@", [NSThread currentThread]);
}];
NSBlockOperation *operation2 = [NSBlockOperation blockOperationWithBlock:^{NSLog(@"下載圖片2---%@", [NSThread currentThread]);
}];
NSBlockOperation *operation3 = [NSBlockOperation blockOperationWithBlock:^{NSLog(@"下載圖片3---%@", [NSThread currentThread]);
}];
NSBlockOperation *operation4 = [NSBlockOperation blockOperationWithBlock:^{NSLog(@"下載圖片4---%@", [NSThread currentThread]);
}];
NSInvocationOperation *operation5 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(download) object:nil];[queue addOperation:operation1];
[queue addOperation:operation2];
[queue addOperation:operation3];
[queue addOperation:operation4];
[queue addOperation:operation5];
[queue addOperationWithBlock:^{NSLog(@"下載圖片5---%@", [NSThread currentThread]);
}];
[queue addOperationWithBlock:^{NSLog(@"下載圖片6---%@", [NSThread currentThread]);
}];
[queue addOperationWithBlock:^{NSLog(@"下載圖片7---%@", [NSThread currentThread]);
}];
[queue addOperationWithBlock:^{NSLog(@"下載圖片8---%@", [NSThread currentThread]);
}];
[queue addOperationWithBlock:^{NSLog(@"下載圖片9---%@", [NSThread currentThread]);
}];[queue cancelAllOperations];

}

  • (void)didReceiveMemoryWarning
    {
    [super didReceiveMemoryWarning];

// [queue cancelAllOperations]; // 取消隊列中的所有任務(不可恢復)
}

  • (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
    {
    // [queue setSuspended:YES]; // 暫停隊列中的所有任務
    }

  • (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
    {
    // [queue setSuspended:NO]; // 恢復隊列中的所有任務
    }

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/247144.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/247144.shtml
英文地址,請注明出處:http://en.pswp.cn/news/247144.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

iOS中如何優化Cell中圖片的下載性能

在iOS開發中使用最為常見的是UITableView&#xff0c;其中UITabelViewCell中下載圖片&#xff0c;會影響用戶下拉刷新UI,導致卡頓&#xff0c;用戶體驗不好&#xff0c;在這篇blog中&#xff0c;我將以一個例子來說明如何優化UITableView下載圖片 1.使用懶加載方式&#xff0c…

【Yoshua Bengio 親自解答】機器學習 81 個問題及答案(最全收錄)

本文轉自&#xff1a;http://mp.weixin.qq.com/s?__bizMzI3MTA0MTk1MA&mid401958262&idx1&sn707f228cf5779a31f0933af903516ba6&scene1&srcid0121zzdeFPtgoRoEviZ3LZDG#rd 譯者&#xff1a;張巨巖 王婉婷 李宏菲 戴秋池 這是 Quora 的最新節目&#xf…

Java生鮮電商平臺-SpringCloud微服務架構中網絡請求性能優化與源碼解析

Java生鮮電商平臺-SpringCloud微服務架構中網絡請求性能優化與源碼解析 說明&#xff1a;Java生鮮電商平臺中&#xff0c;由于服務進行了拆分&#xff0c;很多的業務服務導致了請求的網絡延遲與性能消耗&#xff0c;對應的這些問題&#xff0c;我們應該如何進行網絡請求的優化與…

XCode7 創建framework

1.新建一個靜態庫工程. file→ new→ project, 彈出框中選擇iOS→ framework & library中的cocoa touch static library.點擊Next,輸入product name: TestFramework, 點擊Next→ 點擊Create. 2.刪除向導所生成工程中的Target. 點擊工程名→ 點擊TARGETS → 右鍵Delete. …

基礎js逆向練習-登錄密碼破解(js逆向)

練習平臺&#xff1a;逆向賬號密碼 https://login1.scrape.center/ 直接打開平臺&#xff0c;輸入密碼賬號&#xff0c;抓包找到加密的參數攜帶的位置&#xff0c;這邊我們找到的是一個叫token的加密參數&#xff0c;這個參數的攜帶是一個密文 我們首先考慮一下搜索這個加密的…

python之socket

socket套接字 什么叫socket socket是處于應用層與傳輸層之間的抽象層,他是一組操作起來非常簡單的接口(接受數據)此接口接受數據之后,交由操作系統.socket在python中就是一個模塊. socket兩個分類 基于文件類型的套接字家族 套接字家族的名字&#xff1a;AF_UNIX unix一切皆文件…

iOS----JSON解析

在iOS開發中與服務器進行數據交互操作&#xff0c;操作過程中使用最為常見的格式為JSON與XML,其中JSON較為清量,因此本篇blog就講解一下如何在iOS中進行JSON解析。 1.建立HTTP請求 &#xff08;1&#xff09;創建URL NSString *URLStr [NSString stringWithFormat:”http:/…

VS中每次改代碼后運行程序不更新,只有重新編譯才生效。

解決方法&#xff1a;將項目移除解決方案&#xff0c;再重新添加進來&#xff0c;即添加->現有項目->選擇.vcxproj文件&#xff0c;即可解決。 轉載于:https://www.cnblogs.com/Gregg/p/11358711.html

socket補充:通信循環、鏈接循環、遠程操作及黏包現象

socket補充&#xff1a;通信循環、鏈接循環、遠程操作及黏包現象 socket通信循環 server端&#xff1a; import socketphone socket.socket(socket.AF_INET,socket.SOCK_STREAM)phone.bind((127.0.0.1,8080))phone.listen(5)conn, client_addr phone.accept() print(conn, cl…

PCA的原理及MATLAB實現

相關文章 PCA的原理及MATLAB實現 UFLDL教程&#xff1a;Exercise:PCA in 2D & PCA and Whitening python-A comparison of various Robust PCA implementations &#xff0d;&#xff0d;&#xff0d;&#xff0d;&#xff0d;&#xff0d;&#xff0d;&#xff0d;&a…

Java生鮮電商平臺-SpringCloud微服務架構中核心要點和實現原理

Java生鮮電商平臺-SpringCloud微服務架構中核心要點和實現原理 說明&#xff1a;Java生鮮電商平臺中&#xff0c;我們將進一步理解微服務架構的核心要點和實現原理&#xff0c;為讀者的實踐提供微服務的設計模式&#xff0c;以期讓微服務在讀者正在工作的項目中起到積極的作用。…

iOS中下載小文件

在iOS中通過網絡下載小文件比如小型圖片等資源&#xff0c;一般在子線程中將數據完全下載完畢&#xff0c;然后在調用block將下載的數據整個部分返回&#xff0c;或者采用同步返回下載數據。 一般采用以下兩種方式&#xff1a; &#xff08;1&#xff09;使用GCD將下載操作放…

iOS下載大文件原理解析一

iOS中下載大型文件&#xff0c;需要考慮到占用內存的大小與下載速度&#xff08;使用多線程&#xff09;&#xff0c;因此本文首先介紹一個原理性下載文件的DEMO。 在下載大型文件中&#xff0c;需要知道下載的進度因此需要使用代理模式&#xff0c;不斷的回調下載進度。 - (…

recv原理、高階版黏包解決方案、基于UDP的socket通信

recv原理、高階版黏包解決方案、基于UDP的socket通信 recv原理 源碼解釋&#xff1a; Receive up to buffersize bytes from the socket. 接收來自socket緩沖區的字節數據&#xff0c; For the optional flags argument, see the Unix manual. 對于這些設置的參數&#xff0c;可…

iOS中下載大型文件的原理解析二

在iOS中下載大型文件&#xff0c;需要使用NSURLConnection 的代理方法&#xff1a; (void)touchesBegan:(NSSet)touches withEvent:(UIEvent *)event { NSURL *url [NSURL URLWithString:”http://d.3987.com/fengj_141112/007.jpg“]; NSURLRequest *request [NSURLReque…

ASP.NET Core Web 應用程序開發期間部署到IIS自定義主機域名并附加到進程調試

想必大家之前在進行ASP.NET Web 應用程序開發期間都有用到過將我們的網站部署到IIS自定義主機域名并附加到進程進行調試。 那我們的ASP.NET Core Web 應用程序又是如何部署到我們的IIS上面進行調試的呢&#xff0c;接下來我們來簡單介紹下&#xff1a; 一、安裝IIS所需的Host擴…

iOS下載大型文件原理解析三

在下載大型文件過程中是可以取消下載的 - (IBAction)download:(UIButton *)sender { // 狀態取反 sender.selected !sender.isSelected; // 斷點續傳 // 斷點下載if (sender.selected) { // 繼續&#xff08;開始&#xff09;下載// 1.URLNSURL *url [NSURL URLWithStrin…

HTML文件上傳與下載

文件下載 傳統的文件下載有兩種方法&#xff1a; 使用<a/>標簽&#xff0c;href屬性直接連接到服務器的文件路徑window.location.href"url"這兩種方法效果一樣。但有個很大的問題&#xff0c;如果下載出現異常&#xff08;連接路徑失效、文件不存在、網絡問題等…

NSURLSession的應用

iOS7以后發布了NSURLSession用來替換NSURLConnection&#xff0c;NSURLSession使用方式有以下兩種&#xff1a; 1.block方式 &#xff08;1&#xff09;創建的步驟 獲取單例會話對象 創建URL對象 隱含創建request 創建NSURLSessionDataTask // 1.獲取會話對象 NSURLSess…