iOS - 信號量和GCD高級用法


一、前言

  我們開發的時候老是會遇到一個需求就是,需要多個網絡請求成功后才開始刷新界面,這個時候我們就需要用到GCD 的 dispatch_group_t 方法。

  話不多說開始。

二、代碼

  1、先創建對象

dispatch_group_t group = dispatch_group_create();

  2、循環執行網絡請求

 
         
dispatch_group_enter(group);
for (int i = 0; i < self.seasonList.count; i++) {
        [NetRequest postWithBasicParameters:dict success:^(NSDictionary *arg) {
            //網絡請求成功
            dispatch_group_leave(group);
        } failure:^(NSString *arg) {
            //網絡請求失敗
            dispatch_group_leave(group);
        }];
    }

  注:這里要注意的是無論是網絡請求失敗還是成功,都要調用結束方法,不然會阻塞線程。

  3、等所有循環結束后開始刷新UI

dispatch_group_notify(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
        asyncMainBlock(^{
            [EasyLodingView hidenLoding];
            //排序
            for (int i = 0; i < self.datasource.count ; i++) {
                for (int j = 0 ; j<self.datasource.count-1 ; j++) {
                    NSDictionary *dict_one = self.datasource[j];
                    NSInteger dict_oneNum = [[dict_one objectOrNilForKey:@"seaId"] integerValue];
                    
                    NSDictionary *dict_two = self.datasource[j+1];
                    NSInteger dict_twoNum = [[dict_two objectOrNilForKey:@"seaId"] integerValue];
                    
                    if (dict_oneNum > dict_twoNum) {
                        [self.datasource exchangeObjectAtIndex:j withObjectAtIndex:j+1];
                    }
                }
            }
            
            [self.listTableView reloadData];
        });
    });

  注:我這邊為了數據展示正常需要進行一次冒泡排序,因為每個網絡請求的快慢不一樣。

三、信號量

  1、信號量是用於多線程同步的,跟鎖不一樣的是,信號量不一定是鎖定某一個資源,而是流程上的概念,比如:有A,B兩個線程,B線程要等A線程完成某一任務以后再進行自己下面的步驟,這個任務 並不一定是鎖定某一資源,還可以是進行一些計算或者數據處理之類。

  而對於鎖來說,鎖住的資源無法被其余的線程訪問,從而阻塞線程而實現線程同步。

  2、方法

//創建信號量,參數:信號量的初值,如果小於0則會返回NULL
dispatch_semaphore_create(信號量值)
 
//等待降低信號量
dispatch_semaphore_wait(信號量,等待時間)
 
//提高信號量
dispatch_semaphore_signal(信號量)

  3、舉例

-(void)dispatchSignal{
    dispatch_semaphore_t semaphore = dispatch_semaphore_create(2);   
    dispatch_queue_t quene = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
     
    //任務1
    dispatch_async(quene, ^{
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        NSLog(@"run task 1");
        sleep(1);
        NSLog(@"complete task 1");
        dispatch_semaphore_signal(semaphore);       
    });<br>
    //任務2
    dispatch_async(quene, ^{
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        NSLog(@"run task 2");
        sleep(1);
        NSLog(@"complete task 2");
        dispatch_semaphore_signal(semaphore);       
    });<br>
    //任務3
    dispatch_async(quene, ^{
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        NSLog(@"run task 3");
        sleep(1);
        NSLog(@"complete task 3");
        dispatch_semaphore_signal(semaphore);       
    });   
}

  注:這個和上面的GCD又有點不一樣,上面的是循環執行,這個是控制單次的進程等待的方法。看需求采取固定的方式吧。

  暫時就講這么多吧,下次遇見了其他需求再多說點。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM