iOS開發-GCD和後臺處理

一些生命週期函數的調用時間html

打開應用時,調用ios

applicationWillEnterForeground:併發

applicationDidBecomeActive:app

 

按Home鍵,調用異步

applicationWillResignActive:async

applicationDidEnterBackground:ide

 

雙擊Home鍵,向上滑動關閉程序,調用函數

applicationWillTerminate:ui

 

狀態保存和回覆機制參考url

http://developer.apple.com/library/ios/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/Strategiesfor-ImplementingYourApp/StrategiesforImplementingYourApp.html 的App Programming Guide for iOS

  • GCD的核心概念
    1.任務
    實行什麼操做,即你的代碼。
    2.隊列
    用來存聽任務的,有併發隊列,串行隊列兩種
    併發隊列:多個任務同時執行(只在異步方式dispatch_async執行會起做用)
    串行隊列:多個任務一個一個按順序執行
    > 主隊列是GCD自帶的一種特殊的串行隊列,放在主隊列的任務都會在主線程中執行
  • 使用步驟
    1.定製任務
    // 用同步的方式執行任務,不建立新的線程
    dispatch_sync(<#dispatch_queue_t  _Nonnull queue#>, <#^(void)block#>);
    /*
        參數1:隊列的類型
        參數2:任務,你要執行的代碼
    */
    // 用異步的方式執行任務,自動建立新的線程,在異步的方式下才能併發執行任務
    dispatch_async(<#dispatch_queue_t  _Nonnull queue#>, <#^(void)block#>);
    2.將任務放入隊列
    // 建立一個串行隊列
        dispatch_queue_t queue = dispatch_queue_create("myQueue", NULL);
        // 把4個任務放進去串行隊列中,用異步的方式執行(只會新開一條線程,每一個任務按順序執行)
        dispatch_async(queue, ^{
            NSLog(@"---下載圖片1---%@",[NSThread currentThread]);
        });
        dispatch_async(queue, ^{
            NSLog(@"---下載圖片2---%@",[NSThread currentThread]);
        });
        dispatch_async(queue, ^{
            NSLog(@"---下載圖片3---%@",[NSThread currentThread]);
        });
        dispatch_async(queue, ^{
            NSLog(@"---下載圖片4---%@",[NSThread currentThread]);
        });
    
        // 建立一個併發隊列
        dispatch_queue_t queue1 = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
        // 把4個任務放入併發隊列,用異步的方式執行(會新開4條線程,同時執行4個任務)
        dispatch_async(queue1, ^{
            NSLog(@"---下載圖片1---%@",[NSThread currentThread]);
        });
        dispatch_async(queue1, ^{
            NSLog(@"---下載圖片2---%@",[NSThread currentThread]);
        });
        dispatch_async(queue1, ^{
            NSLog(@"---下載圖片3---%@",[NSThread currentThread]);
        });
        dispatch_async(queue1, ^{
            NSLog(@"---下載圖片4---%@",[NSThread currentThread]);
        });

    // 若是在同步dispatch_sync中執行,不管在什麼隊列,全部任務都是按順序執行的,由於它不開線程

     

  • GCD中線程間的通訊
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
       // 執行耗時的異步操做...
        
        
       dispatch_async(dispatch_get_main_queue(), ^{
           // 回到主線程,執行UI刷新操做
       });
    });

     

  • 延時執行
    1> performSelector
    // 3秒後自動回到當前線程調用self的download:方法,而且傳遞參數:@"http://555.jpg"
    [self performSelector:@selector(download:) withObject:@"http://555.jpg" afterDelay:3];
    
    2> dispatch_after...第一個參數:延時時間;第二個參數,延時以後在什麼隊列執行
    // 任務放到哪一個隊列中執行
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    double delay = 3; // 延遲多少秒
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delay * NSEC_PER_SEC)), queue, ^{
        // 3秒後須要執行的任務
    });

     

  • GCD實現一次性代碼
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        // 這裏面的代碼,在程序運行過程當中,永遠只會執行1次
    });

     

  • GCD中的隊列組
    使用隊列組能確保組中的任務所有執行完,再去執行其餘代碼
        // 1.建立隊列組和全局(併發)隊列
        dispatch_group_t group = dispatch_group_create();
        dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
        
        // 2.下載圖片1
        __block UIImage *image1 = nil;
        dispatch_group_async(group, queue, ^{
            NSURL *url1 = [NSURL URLWithString:@"http://g.hiphotos.baidu.com/image/pic/item/f2deb48f8c5494ee460de6182ff5e0fe99257e80.jpg"];
            NSData *data1 = [NSData dataWithContentsOfURL:url1];
            image1 = [UIImage imageWithData:data1];
        });
        
        // 3.下載圖片2
        __block UIImage *image2 = nil;
        dispatch_group_async(group, queue, ^{
            NSURL *url2 = [NSURL URLWithString:@"http://su.bdimg.com/static/superplus/img/logo_white_ee663702.png"];
            NSData *data2 = [NSData dataWithContentsOfURL:url2];
            image2 = [UIImage imageWithData:data2];
        });
        
        // 4.合併圖片 (保證執行完組裏面的全部任務以後,再執行notify函數裏面的block)
        dispatch_group_notify(group, queue, ^{
            // 開啓一個位圖上下文
            UIGraphicsBeginImageContextWithOptions(image1.size, NO, 0.0);
            
            // 繪製第1張圖片
            CGFloat image1W = image1.size.width;
            CGFloat image1H = image1.size.height;
            [image1 drawInRect:CGRectMake(0, 0, image1W, image1H)];
            
            // 繪製第2張圖片
            CGFloat image2W = image2.size.width * 0.5;
            CGFloat image2H = image2.size.height * 0.5;
            CGFloat image2Y = image1H - image2H;
            [image2 drawInRect:CGRectMake(0, image2Y, image2W, image2H)];
            
            // 獲得上下文中的圖片
            UIImage *fullImage = UIGraphicsGetImageFromCurrentImageContext();
            
            // 結束上下文
            UIGraphicsEndImageContext();
            
            // 5.回到主線程顯示圖片
            dispatch_async(dispatch_get_main_queue(), ^{
                self.imageView.image = fullImage;
            });
        });
相關文章
相關標籤/搜索