iOS 信號量解決-網絡異步請求的數據同步返回問題


 

有那么一個場景如下

+PayWithBlock:(NSString*(^)(NSString *message)) block;

 如果 block 返回是同步的那是沒有問題的,但是如果block 內容需要網絡請求后才能得到,那如何處理,如下

Client {

    //開始調用
    
    [Pay PayWithBlock:NSString *(^)( NSString *message) {
      //異步網絡請求數據
      
      return @"test";  
    }];
}

 如果不做任何處理是無法得到網絡請求的數據結果的, 因此我們在這里需要使用信號量來處理,思路如下:

 // 設置一個異步線程組
        // 設置一個網絡請求
        NSURLRequest *request = [[NSURLRequest alloc] initWithURL:[NSURL URLWithString:@"https://www.github.com"]];
        // 創建一個信號量為0的信號(紅燈)
        dispatch_semaphore_t sema = dispatch_semaphore_create(0);
        NSURLSessionDownloadTask *task = [[NSURLSession sharedSession] downloadTaskWithRequest:request completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) {
            NSLog(@"第一步操作");
            // 使信號的信號量+1,這里的信號量本來為0,+1信號量為1(綠燈)
            dispatch_semaphore_signal(sema);
        }];
        [task resume];
        // 以下還要進行一些其他的耗時操作
        NSLog(@"耗時操作繼續進行");
        // 開啟信號等待,設置等待時間為永久,直到信號的信號量大於等於1(綠燈)
        dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
        NSLog(@"dispatch_semaphore_wait_end");

 

整合一起代碼如下:

Client {

    //開始調用
    
    [Pay PayWithBlock:NSString *(^)( NSString *message) {         // 設置一個網絡請求     __block  NSString *result = nil;
         NSURLRequest *request = [[NSURLRequest alloc] initWithURL:[NSURL URLWithString:@"https://www.github.com"]];
        // 創建一個信號量為0的信號(紅燈)
        dispatch_semaphore_t sema = dispatch_semaphore_create(0);    
        NSURLSessionDownloadTask *task = [[NSURLSession sharedSession] downloadTaskWithRequest:request completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) {
            NSLog(@"第一步操作");
            // 使信號的信號量+1,這里的信號量本來為0,+1信號量為1(綠燈)           result = @"我是網絡請求數據";
            dispatch_semaphore_signal(sema);
        }];
        [task resume];
        // 以下還要進行一些其他的耗時操作
        NSLog(@"耗時操作繼續進行");
        // 開啟信號等待,設置等待時間為永久,直到信號的信號量大於等於1(綠燈)
        dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
        NSLog(@"dispatch_semaphore_wait_end");      
     return resutl; }];}

方案二 、使用dispatch_group_enter(group),dispatch_group_leave(group) 待續


免責聲明!

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



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