標籤:操作 nsoperation 網路 多線程 ios
貓貓分享,必須精品
原創文章,歡迎轉載。轉載請註明:翟乃玉的部落格
地址:http://blog.csdn.net/u013357243?viewmode=contents
一:隊列的類型與隊列新增工作1: 主隊列
- [NSOperationQueue mainQueue]
- 添加到”主隊列”中的操作,都會放到主線程中執行。
2:非主隊列
- [[NSOperationQueue alloc] init]
- 添加到”非主隊列”中的操作,都會放到子線程中執行。
3:隊列新增工作
-
- (void)addOperation:(NSOperation *)op;
-
- (void)addOperationWithBlock:(void (^)(void))block;
二:常見用法1: 設定最大並發數
(1)並發數:同時執?行的任務數.比如,同時開3個線程執行3個任務,並發數就是3。
(2)最大並發數:同一時間最多隻能執行的任務的個數。
(3)最?大並發數的相關?方法。
- (NSInteger)maxConcurrentOperationCount;
- (void)setMaxConcurrentOperationCount:(NSInteger)cnt;
說明:如果沒有設定最大並發數,那麼並發的個數是由系統記憶體和CPU決定的,可能記憶體多久開多一點,記憶體少就開少一點。
注意:num的值並不代表線程的個數,僅僅代表線程的ID。
提示:最大並發數不要亂寫(5以內),不要開太多,一般以2~3為宜,因為雖然任務是在子線程進行處理的,但是cpu處理這些過多的子線程可能會影響UI,讓UI變卡。
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{ // 1.建立一個隊列(非主隊列) NSOperationQueue *queue = [[NSOperationQueue alloc] init]; // 2.設定最大並發(最多同時並發執行2個任務) queue.maxConcurrentOperationCount = 2; // 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]); }];}
效果:我們設定了9個類比下載的操作,同一時間開啟的線程最多為兩個,注意,途中有2,3,4 三條線程,但是我們保證了再同一時間只有兩條線程,2開始做事,後來不做了,就換線程3,4了。
2: 隊列的其他動作
- 取消所有的操作
- (void)cancelAllOperations;
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{ // 1.建立一個隊列(非主隊列) NSOperationQueue *queue = [[NSOperationQueue alloc] init];// // 2.設定最大並發(最多同時並發執行2個任務)// queue.maxConcurrentOperationCount = 2; // 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]; // 取消隊列中的所有任務(不可恢複)}
跟取消所有操作差不多,實際情況中這樣用,當我們的tableview跟客戶互動的時候(滾動)暫停,不互動了繼續執行
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView{// [queue setSuspended:YES]; // 暫停隊列中的所有任務}- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate{// [queue setSuspended:NO]; // 恢複隊列中的所有任務}
三:操作之間的依賴(面試題)
- NSOperation之間可以設定依賴來保證執行順序
- [operationB addDependency:operationA];
// 操作B依賴於操作A,等操作A執行完畢後,才會執行操作B
- 注意:不能相互依賴,比如A依賴B,B依賴A
- 可以在不同queue的NSOperation之間建立依賴關係
簡單來說就是讓線程執行有順序,是一個執行依賴於另一個線程的執行。
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{ /** 假設有A、B、C三個操作,要求: 1. 3個操作都非同步執行 2. 操作C依賴於操作B 3. 操作B依賴於操作A */ // 1.建立一個隊列(非主隊列) NSOperationQueue *queue = [[NSOperationQueue alloc] init]; // 2.建立3個操作 NSBlockOperation *operationA = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"A---%@", [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];}
效果
四:線程之間的通訊
NSOperationQueue *queue = [[NSOperationQueue alloc] init];[queue addOperationWithBlock:^{ // 1.執行一些比較耗時的操作的代碼 [[NSOperationQueue mainQueue] addOperationWithBlock:^{ // 2.回到主線程操作的代碼 }];}];
這個回看前面下載圖片類似的案例就可以了。就是在子線程執行瞭然後會回主線程進行操作。
貓貓學iOS(五十四)多線程網路之NSOperation重要知識