iOS GCD基本使用及詳解

GCD的基本函數(shù):

  • dispatch_sync() 同步執(zhí)行
  • dispatch_async() 異步執(zhí)行
  • dispatch_after() 延時(shí)執(zhí)行
  • dispatch_once() 一次性執(zhí)行
  • dispatch_apply() 提交隊(duì)列
  • dispatch_queue_create() 創(chuàng)建隊(duì)列
  • dispatch_group_create() 創(chuàng)建隊(duì)列組
  • dispatch_group_async() 提交任務(wù)到隊(duì)列組
  • dispatch_group_enter() / dispatch_group_leave() 將隊(duì)列組中的任務(wù)未執(zhí)行完畢的任務(wù)數(shù)目加減1(兩個(gè)函數(shù)要配合使用)
  • dispatch_group_notify() 監(jiān)聽(tīng)隊(duì)列組執(zhí)行完畢
  • dispatch_group_wait() 設(shè)置等待時(shí)間(返回 0成功,1失敗)

隊(duì)列:

GCD 用dispatch queue來(lái)處理代碼塊只磷,這些隊(duì)列管理你提供給 GCD 的任務(wù)并執(zhí)行這些任務(wù)钮追。這就保證了第一個(gè)被添加到隊(duì)列里的任務(wù)會(huì)是隊(duì)列中第一個(gè)開(kāi)始的任務(wù),而第二個(gè)被添加的任務(wù)將第二個(gè)開(kāi)始轧叽,如此直到隊(duì)列的終點(diǎn)惠毁。

  • 主隊(duì)列:系統(tǒng)提供的一個(gè)特殊隊(duì)列鞠绰。和其它串行隊(duì)列一樣,這個(gè)隊(duì)列中的任務(wù)一次只能執(zhí)行一個(gè)屿笼。它能保證所有的任務(wù)都在主線程執(zhí)行驴一,而主線程是唯一可用于更新 UI 的線程。這個(gè)隊(duì)列就是用來(lái)在主線程上進(jìn)行操作的杈曲。
  • 串行隊(duì)列:串行隊(duì)列中的任務(wù)一次執(zhí)行一個(gè)担扑,每個(gè)任務(wù)只會(huì)在上一個(gè)任務(wù)完成時(shí)才開(kāi)始執(zhí)行趣钱。
  • 并發(fā)隊(duì)列:在并發(fā)隊(duì)列中的任務(wù)會(huì)按照被添加的順序開(kāi)始執(zhí)行首有,任務(wù)可能以任意順序完成,你不能知道什么時(shí)開(kāi)始執(zhí)行下一個(gè)任務(wù)卜壕,或者有多少任務(wù)在同時(shí)執(zhí)行低矮。
//獲取主隊(duì)列
dispatch_queue_t mainQueue = dispatch_get_main_queue();
//使用dispatch_get_global_queue()獲取全局并發(fā)隊(duì)列,第一個(gè)參數(shù)是隊(duì)列優(yōu)先級(jí),第二個(gè)參數(shù)傳0.
dispatch_queue_t otherQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
/** 
  * 使用 dispatch_queue_create 初始化 concurrentQueue 為一個(gè)并發(fā)隊(duì)列军掂。
  * 第一個(gè)參數(shù)是隊(duì)列標(biāo)識(shí)蝗锥;第二個(gè)參數(shù)指定你的隊(duì)列是串行還是并發(fā)率触。設(shè)為NULL時(shí)默認(rèn)是DISPATCH_QUEUE_SERIAL葱蝗,將創(chuàng)建串行隊(duì)列.
  * 在必要情況下,你可以將其設(shè)置為DISPATCH_QUEUE_CONCURRENT來(lái)創(chuàng)建自定義并行隊(duì)列.
 */
dispatch_queue_t myQueue = dispatch_queue_create("myQueue", DISPATCH_QUEUE_CONCURRENT);

同步和異步:

//同步函數(shù),在當(dāng)前線程執(zhí)行(不開(kāi)啟新的線程)
dispatch_sync(otherQueue, ^{
    NSLog(@"同步:%@",[NSThread currentThread]);
});

//異步函數(shù),開(kāi)啟子線程執(zhí)行
dispatch_async(otherQueue, ^{
    NSLog(@"異步:%@",[NSThread currentThread]);
});
打印:
[15276:540462] 同步:<NSThread: 0x600000068680>{number = 1, name = main}
[15276:540519] 異步:<NSThread: 0x600000074a80>{number = 3, name = (null)}

串行隊(duì)列:

一個(gè)任務(wù)執(zhí)行完畢后皂甘,再執(zhí)行下一個(gè)任務(wù)

  • 異步
// 1.使用 dispatch_queue_creat()創(chuàng)建串行隊(duì)列
dispatch_queue_t serialQueue = dispatch_queue_create("serialQueue", NULL);

//開(kāi)啟新線程,串行執(zhí)行任務(wù)
NSLog(@"異步函數(shù)執(zhí)行串行隊(duì)列,當(dāng)前線程:%@",[NSThread currentThread]);
dispatch_async(serialQueue, ^{
    NSLog(@"任務(wù)1:%@",[NSThread currentThread]);
});

dispatch_async(serialQueue, ^{
    NSLog(@"任務(wù)2:%@",[NSThread currentThread]);
});

dispatch_async(serialQueue, ^{
    NSLog(@"任務(wù)3:%@",[NSThread currentThread]);
});
  • 同步
//不開(kāi)啟新線程,串行執(zhí)行任務(wù)
NSLog(@"同步函數(shù)執(zhí)行串行隊(duì)列,當(dāng)前線程:%@",[NSThread currentThread]);

dispatch_sync(serialQueue, ^{
    NSLog(@"任務(wù)1:%@",[NSThread currentThread]);
});

dispatch_sync(serialQueue, ^{
    NSLog(@"任務(wù)2:%@",[NSThread currentThread]);
});

dispatch_sync(serialQueue, ^{
    NSLog(@"任務(wù)3:%@",[NSThread currentThread]);
});
并發(fā)隊(duì)列:
  • 多個(gè)任務(wù)并發(fā)執(zhí)行(自動(dòng)開(kāi)啟多個(gè)線程同時(shí)執(zhí)行任務(wù))
  • 并發(fā)功能只有在異步(dispatch_async)函數(shù)下才有效!
dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

//異步函數(shù),并發(fā)隊(duì)列
//開(kāi)啟新線程,并發(fā)執(zhí)行任務(wù)
NSLog(@"異步函數(shù)執(zhí)行并發(fā)隊(duì)列,當(dāng)前線程:%@",[NSThread currentThread]);
dispatch_async(concurrentQueue, ^{
    NSLog(@"任務(wù)1:%@",[NSThread currentThread]);
});

dispatch_async(concurrentQueue, ^{
    NSLog(@"任務(wù)2:%@",[NSThread currentThread]);
});

dispatch_async(concurrentQueue, ^{
   NSLog(@"任務(wù)3:%@",[NSThread currentThread]);
});
隊(duì)列組:

任務(wù)1,任務(wù)2同時(shí)執(zhí)行,所有任務(wù)都執(zhí)行成功后回到主線程,高效率

NSLog(@"隊(duì)列組執(zhí)行任務(wù),當(dāng)前線程:%@",[NSThread currentThread]);
//1.創(chuàng)建隊(duì)列組 dispatch_group_create()
dispatch_group_t group = dispatch_group_create();

//2.開(kāi)啟任務(wù)
//開(kāi)啟任務(wù)1
//提交任務(wù)到隊(duì)列組 dispatch_group_async()
dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    for (int i = 0; i < 5; i++) {
        NSLog(@"任務(wù)1 :%@",[NSThread currentThread]);
    }
});

//開(kāi)啟任務(wù)2
dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    for (int i = 0; i < 5; i++) {
        NSLog(@"任務(wù)2 :%@",[NSThread currentThread]);
    }
});

//所有任務(wù)執(zhí)行完畢,回到主線程進(jìn)行操作
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
    NSLog(@"任務(wù)1,2執(zhí)行完畢,回到主線程:%@",[NSThread currentThread]);
});

延時(shí)執(zhí)行:

延遲一段時(shí)間把一項(xiàng)任務(wù)提交到隊(duì)列中執(zhí)行,返回之后就不能取消嗤锉,常用來(lái)在主隊(duì)列上延遲執(zhí)行一項(xiàng)任務(wù)墓塌。

NSLog(@"當(dāng)前線程 %@", [NSThread currentThread]);
//GCD延時(shí)調(diào)用(主線程)(主隊(duì)列)
/**
 * 1.聲明一個(gè)變量 afterTime 指定要延遲的時(shí)長(zhǎng)
 * 2.等待 afterTime 給定的時(shí)長(zhǎng)苫幢,再異步地添加一個(gè) Block 到主線程。
 */
dispatch_time_t afterTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC));//1

dispatch_after(afterTime, dispatch_get_main_queue(), ^{//2
    NSLog(@"GCD延時(shí)調(diào)用(主線程):%@",[NSThread currentThread]);
});

//GCD延時(shí)調(diào)用(其他線程)(全局并發(fā)隊(duì)列)
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    NSLog(@"GCD延時(shí)調(diào)用(其他線程):%@",[NSThread currentThread]);
});
打印:
[15276:540462] 當(dāng)前線程 <NSThread: 0x600000068680>{number = 1, name = main}
[15276:540462] GCD延時(shí)調(diào)用(主線程):<NSThread: 0x600000068680>{number = 1, name = main}
[15276:540521] GCD延時(shí)調(diào)用(其他線程):<NSThread: 0x60800007c940>{number = 4, name = (null)}

dispatch_once()

在整個(gè)程序運(yùn)行中,代碼會(huì)以線程安全的方式執(zhí)行并且只執(zhí)行一次

for (int i = 0 ; i < 99999; i++) {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        NSLog(@"執(zhí)行一次:%d",i);
    });
}

dispatch_barrier_async()

讀者寫者鎖(柵欄函數(shù))

  • 在進(jìn)程管理中起到一個(gè)柵欄的作用,它等待所有位于barrier函數(shù)之前的操作執(zhí)行完畢后執(zhí)行
  • 在barrier函數(shù)執(zhí)行之后,barrier函數(shù)之后的操作才會(huì)得到執(zhí)行
    作用:
    1.實(shí)現(xiàn)高效率的數(shù)據(jù)庫(kù)訪問(wèn)和文件訪問(wèn)
    2.避免數(shù)據(jù)競(jìng)爭(zhēng)

使用:

    dispatch_queue_t queue = dispatch_queue_create("barrier", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue, ^{
    NSLog(@"任務(wù)1:%@",[NSThread currentThread]);
});

dispatch_async(queue, ^{
    NSLog(@"任務(wù)2:%@",[NSThread currentThread]);
});

dispatch_barrier_async(queue, ^{
    NSLog(@"---barrier---:%@",[NSThread currentThread]);
});

dispatch_async(queue, ^{
    NSLog(@"任務(wù)3:%@",[NSThread currentThread]);
});

dispatch_async(queue, ^{
    NSLog(@"任務(wù)4:%@",[NSThread currentThread]);
});

解決多個(gè)網(wǎng)絡(luò)請(qǐng)求全部發(fā)送后再進(jìn)行操作的問(wèn)題方案:

1.Dispatch Group

對(duì)多個(gè)異步任務(wù)的完成進(jìn)行監(jiān)控
代碼中的注釋:

  1. 創(chuàng)建一個(gè)新的 Dispatch Group,它相當(dāng)于一個(gè)用來(lái)記錄未完成任務(wù)的計(jì)數(shù)器玫氢。
  • dispatch_group_enter,手動(dòng)通知 Dispatch Group 任務(wù)已經(jīng)開(kāi)始
  • dispatch_group_leave,手動(dòng)通知 Dispatch Group 任務(wù)已經(jīng)完成
  • dispatch_group_notify,當(dāng) Dispatch Group 中沒(méi)有任何任務(wù)時(shí)會(huì)執(zhí)行漾峡。

注意:

  • 必須保證 dispatch_group_enter 和 dispatch_group_leave 成對(duì)出現(xiàn)喻旷,確保進(jìn)入 Group 的次數(shù)和離開(kāi) Group 的次數(shù)相等且预。
    - (IBAction)requestForData:(id)sender
    {
        __block NSMutableDictionary *errDict = [NSMutableDictionary dictionaryWithCapacity:0];
        __block NSMutableDictionary *successDic = [NSMutableDictionary dictionaryWithCapacity:0];

        dispatch_group_t requestGroup = dispatch_group_create();//1
    
        for(NSInteger i=1 ; i<4 ;i++)
        {
            dispatch_group_enter(requestGroup);//2
            [self requestForDataWithIndex:i block:^(NSArray *dataArray, NSInteger index, BOOL isSuccess) {
                if (isSuccess) {
                    NSLog(@"第%ld個(gè)網(wǎng)絡(luò)請(qǐng)求成功锋谐,返回參數(shù)是:%@",(long)index,dataArray);
                    [successDic setObject:dataArray forKey:[NSNumber numberWithInteger:index]];
                }else{
                    NSLog(@"第%ld個(gè)網(wǎng)絡(luò)請(qǐng)求失敗,返回參數(shù)是:%@",(long)index,dataArray);
                    [errDict setObject:dataArray forKey:[NSNumber numberWithInteger:index]];
                }
                dispatch_group_leave(requestGroup);//3
            }];
        }
        dispatch_group_notify(requestGroup, dispatch_get_main_queue(), ^{//4
            //請(qǐng)求完成乾戏,主線程操作
            NSLog(@"請(qǐng)求全部完成鼓择,成功數(shù)據(jù):%@,失敗數(shù)據(jù):%@",successDic,errDict);
        });
    }
打印
2017-03-21 14:11:42.098 GCD-Demo[15276:540462] 發(fā)起第1個(gè)網(wǎng)絡(luò)請(qǐng)求:<NSThread: 0x600000068680>{number = 1, name = main}
2017-03-21 14:11:42.098 GCD-Demo[15276:540462] 發(fā)起第2個(gè)網(wǎng)絡(luò)請(qǐng)求:<NSThread: 0x600000068680>{number = 1, name = main}
2017-03-21 14:11:42.099 GCD-Demo[15276:540462] 發(fā)起第3個(gè)網(wǎng)絡(luò)請(qǐng)求:<NSThread: 0x600000068680>{number = 1, name = main}
2017-03-21 14:11:43.190 GCD-Demo[15276:540462] 第1個(gè)網(wǎng)絡(luò)請(qǐng)求成功就漾,返回參數(shù)是:(
1
)
2017-03-21 14:11:43.599 GCD-Demo[15276:540462] 第3個(gè)網(wǎng)絡(luò)請(qǐng)求成功从藤,返回參數(shù)是:(
1
)
2017-03-21 14:11:44.599 GCD-Demo[15276:540462] 第2個(gè)網(wǎng)絡(luò)請(qǐng)求失敗锁蠕,返回參數(shù)是:(
0
)
2017-03-21 14:11:44.599 GCD-Demo[15276:540462] 請(qǐng)求全部完成荣倾,成功數(shù)據(jù):{
    3 =     (
        1
    );
    1 =     (
        1
    );
},失敗數(shù)據(jù):{
    2 =     (
        0
    );
}

2.dispatch_apply()

提交隊(duì)列,適用于并發(fā)循環(huán).

- (IBAction)requestForData_Dispatch_apply:(id)sender
{
/**
 dispatch_apply() 

 @param iterations 迭代的次數(shù)
 @param queue 指定任務(wù)運(yùn)行的隊(duì)列
 @param size_t Block
 */
//    dispatch_apply(size_t iterations, dispatch_queue_t  _Nonnull queue, ^(size_t) {})

    __block NSMutableDictionary *errDict = [NSMutableDictionary dictionaryWithCapacity:0];
    __block NSMutableDictionary *successDic = [NSMutableDictionary dictionaryWithCapacity:0];
    dispatch_group_t requestGroup = dispatch_group_create();
    dispatch_apply(3, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(size_t i) {
        dispatch_group_enter(requestGroup);
        [self requestForDataWithIndex:i block:^(NSArray *dataArray, NSInteger index, BOOL isSuccess) {
            if (isSuccess) {
                NSLog(@"第%ld個(gè)網(wǎng)絡(luò)請(qǐng)求成功舌仍,返回參數(shù)是:%@",(long)index,dataArray);
                [successDic setObject:dataArray forKey:[NSNumber numberWithInteger:index]];
            }
            else
            {
                NSLog(@"第%ld個(gè)網(wǎng)絡(luò)請(qǐng)求失敗铸豁,返回參數(shù)是:%@",(long)index,dataArray);
                [errDict setObject:dataArray forKey:[NSNumber numberWithInteger:index]];
            }
            dispatch_group_leave(requestGroup);
        }];
    });
    dispatch_group_notify(requestGroup, dispatch_get_main_queue(), ^{
        //請(qǐng)求完成菊碟,主線程操作
        NSLog(@"請(qǐng)求全部完成,成功數(shù)據(jù):%@,失敗數(shù)據(jù):%@",successDic,errDict);
    })
}
打印
2017-03-21 14:15:36.897 GCD-Demo[15276:540462] 發(fā)起第0個(gè)網(wǎng)絡(luò)請(qǐng)求:<NSThread: 0x600000068680>{number = 1, name = main}
2017-03-21 14:15:36.897 GCD-Demo[15276:540521] 發(fā)起第1個(gè)網(wǎng)絡(luò)請(qǐng)求:<NSThread: 0x60800007c940>{number = 4, name = (null)}
2017-03-21 14:15:36.897 GCD-Demo[15276:612863] 發(fā)起第2個(gè)網(wǎng)絡(luò)請(qǐng)求:<NSThread: 0x600000260400>{number = 5, name = (null)}
2017-03-21 14:15:37.993 GCD-Demo[15276:540462] 第1個(gè)網(wǎng)絡(luò)請(qǐng)求成功,返回參數(shù)是:(
1
)
2017-03-21 14:15:38.897 GCD-Demo[15276:540462] 第0個(gè)網(wǎng)絡(luò)請(qǐng)求成功魄幕,返回參數(shù)是:(
1
)
2017-03-21 14:15:39.398 GCD-Demo[15276:540462] 第2個(gè)網(wǎng)絡(luò)請(qǐng)求失敗纯陨,返回參數(shù)是:(
0
)
2017-03-21 14:15:39.398 GCD-Demo[15276:540462] 請(qǐng)求全部完成,成功數(shù)據(jù):{
0 =     (
    1
);
1 =     (
    1
);
},失敗數(shù)據(jù):{
2 =     (
    0
);
}

3.Dispatch Semaphore 信號(hào)量

  1. 信號(hào)量為0時(shí) 會(huì)阻塞線程咙轩,一直等待
  • dispatch_semaphore_wait(信號(hào)量,等待時(shí)間) 這個(gè)函數(shù)會(huì)使傳入的信號(hào)量的值-1;
  • dispatch_semaphore_signal (信號(hào)量) 這個(gè)函數(shù)會(huì)使傳入的信號(hào)量的值+1;
  • 正常的使用順序是先降低然后再提高臭墨,這兩個(gè)函數(shù)通常成對(duì)使用膘盖。

信號(hào)量的理解:

  • 信號(hào)量相當(dāng)于一個(gè)停車場(chǎng),創(chuàng)建時(shí)的參數(shù)相當(dāng)于提供多少個(gè)車位,如果你有兩個(gè)車位,有4輛車要停,那么,只能讓先進(jìn)來(lái)的兩個(gè)車子停下,后面的兩個(gè)車子等待,開(kāi)走一個(gè),才能停入下一個(gè).dispatch_semaphore_wait函數(shù)就相當(dāng)于來(lái)了一輛車,調(diào)用一次,車位就-1.dispatch_semaphore_signal函數(shù)相當(dāng)于走了一輛車,調(diào)用一次,車位就+1.
- (IBAction)requestForData_Dispatch_semaphore_t:(id)sender
{   
    __block NSMutableDictionary *errDict = [NSMutableDictionary dictionaryWithCapacity:0];
    __block NSMutableDictionary *successDic = [NSMutableDictionary dictionaryWithCapacity:0];

    //創(chuàng)建一個(gè)信號(hào)量侠畔。參數(shù)指定信號(hào)量的起始值(必須大于0)
    dispatch_semaphore_t semaphore = dispatch_semaphore_create(2);
    for (NSInteger i=0; i<4; i++) {
    
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        
            dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);//信號(hào)量-1
            [self requestForDataWithIndex:i block:^(NSArray *dataArray, NSInteger index, BOOL isSuccess) {
                if (isSuccess) {
                    NSLog(@"第%ld個(gè)網(wǎng)絡(luò)請(qǐng)求成功软棺,返回參數(shù)是:%@",(long)index,dataArray);
                    [successDic setObject:dataArray forKey:[NSNumber numberWithInteger:index]];
                }
                else
                {
                    NSLog(@"第%ld個(gè)網(wǎng)絡(luò)請(qǐng)求失敗尤勋,返回參數(shù)是:%@",(long)index,dataArray);
                    [errDict setObject:dataArray forKey:[NSNumber numberWithInteger:index]];
                }
                dispatch_semaphore_signal(semaphore);//信號(hào)量+1
            }];
        
        });
    }
}
打印:

這里我代碼中設(shè)置信號(hào)量的起始值為2 ,就會(huì)同時(shí)發(fā)起0和1兩個(gè)任務(wù).0任務(wù)耗時(shí)長(zhǎng),1任務(wù)先返回后立即發(fā)起了任務(wù)2,0任務(wù)結(jié)束后立即發(fā)起了任務(wù)3.

2017-03-21 14:18:11.150 GCD-Demo[15276:613982] 發(fā)起第0個(gè)網(wǎng)絡(luò)請(qǐng)求:<NSThread: 0x60800007fe80>{number = 6, name = (null)}
2017-03-21 14:18:11.150 GCD-Demo[15276:612860] 發(fā)起第1個(gè)網(wǎng)絡(luò)請(qǐng)求:<NSThread: 0x608000064280>{number = 7, name = (null)}
2017-03-21 14:18:12.249 GCD-Demo[15276:540462] 第1個(gè)網(wǎng)絡(luò)請(qǐng)求成功,返回參數(shù)是:(
1
)
2017-03-21 14:18:12.249 GCD-Demo[15276:613984] 發(fā)起第2個(gè)網(wǎng)絡(luò)請(qǐng)求:<NSThread: 0x600000078880>{number = 8, name = (null)}
2017-03-21 14:18:13.151 GCD-Demo[15276:540462] 第0個(gè)網(wǎng)絡(luò)請(qǐng)求成功稀火,返回參數(shù)是:(
1
)
2017-03-21 14:18:13.151 GCD-Demo[15276:613985] 發(fā)起第3個(gè)網(wǎng)絡(luò)請(qǐng)求:<NSThread: 0x600000077380>{number = 9, name = (null)}
2017-03-21 14:18:14.652 GCD-Demo[15276:540462] 第3個(gè)網(wǎng)絡(luò)請(qǐng)求成功凰狞,返回參數(shù)是:(
1
)
2017-03-21 14:18:14.749 GCD-Demo[15276:540462] 第2個(gè)網(wǎng)絡(luò)請(qǐng)求失敗沛慢,返回參數(shù)是:(
0
)
  • 注: 這里只是為了理解信號(hào)量而提供的一種思路...看看就好,不要抬杠...

最后,附上我用來(lái)模擬網(wǎng)絡(luò)請(qǐng)求的代碼:

//模擬網(wǎng)絡(luò)請(qǐng)求
- (void)requestForDataWithIndex:(NSInteger)index block:(Complete)callback
{
    NSLog(@"發(fā)起第%ld個(gè)網(wǎng)絡(luò)請(qǐng)求:%@",(long)index,[NSThread currentThread]);
    NSArray * successArray = [NSArray arrayWithObjects:@1, nil];
    NSArray * failureArray = [NSArray arrayWithObjects:@0, nil];
    if (index == 0) {
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            if (callback) {
                callback(successArray,index,YES);
            }
        });
    }
    else if (index == 1) {
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            if (callback) {
                callback(successArray,index,YES);
            }
        });
    }
    else if (index == 2)
    {
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            if (callback) {
                callback(failureArray,index,NO);
            }
        });
    }
    else if (index == 3)
    {
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            if (callback) {
                callback(successArray,index,YES);
            }
        });
    }

}

另附上demo鏈接

Demo在這里下載...
路漫漫其修遠(yuǎn)兮...

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末逾冬,一起剝皮案震驚了整個(gè)濱河市身腻,隨后出現(xiàn)的幾起案子圾另,更是在濱河造成了極大的恐慌,老刑警劉巖去件,帶你破解...
    沈念sama閱讀 218,858評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件尤溜,死亡現(xiàn)場(chǎng)離奇詭異汗唱,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)授霸,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門碘耳,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)框弛,“玉大人,你說(shuō)我怎么就攤上這事斗搞∑Х伲” “怎么了?”我有些...
    開(kāi)封第一講書人閱讀 165,282評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵澡屡,是天一觀的道長(zhǎng)驶鹉。 經(jīng)常有香客問(wèn)我铣墨,道長(zhǎng),這世上最難降的妖魔是什么姚淆? 我笑而不...
    開(kāi)封第一講書人閱讀 58,842評(píng)論 1 295
  • 正文 為了忘掉前任腌逢,我火速辦了婚禮超埋,結(jié)果婚禮上霍殴,老公的妹妹穿的比我還像新娘。我一直安慰自己妒蔚,他們只是感情好月弛,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,857評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布帽衙。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪冀泻。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 51,679評(píng)論 1 305
  • 那天胳施,我揣著相機(jī)與錄音肢专,去河邊找鬼博杖。 笑死,一個(gè)胖子當(dāng)著我的面吹牛哩盲,可吹牛的內(nèi)容都是我干的狈醉。 我是一名探鬼主播苗傅,決...
    沈念sama閱讀 40,406評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼嘶炭!你這毒婦竟也來(lái)了摇庙?” 一聲冷哼從身側(cè)響起卫袒,我...
    開(kāi)封第一講書人閱讀 39,311評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤夕凝,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后逮矛,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體转砖,經(jīng)...
    沈念sama閱讀 45,767評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年汞窗,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了仲吏。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蝌焚。...
    茶點(diǎn)故事閱讀 40,090評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡只洒,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出舞吭,到底是詐尸還是另有隱情析珊,我是刑警寧澤忠寻,帶...
    沈念sama閱讀 35,785評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站衷旅,受9級(jí)特大地震影響柿顶,放射性物質(zhì)發(fā)生泄漏操软。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,420評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望藏澳。 院中可真熱鬧翔悠,春花似錦野芒、人聲如沸腻要。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,988評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)咽笼。三九已至,卻和暖如春媳纬,著一層夾襖步出監(jiān)牢的瞬間施掏,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,101評(píng)論 1 271
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留狸驳,地道東北人耙箍。 一個(gè)月前我還...
    沈念sama閱讀 48,298評(píng)論 3 372
  • 正文 我出身青樓辩昆,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親遮斥。 傳聞我的和親對(duì)象是個(gè)殘疾皇子扇丛,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,033評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • GCD筆記 總結(jié)一下多線程部分,最強(qiáng)大的無(wú)疑是GCD,那么先從這一塊部分講起. Dispatch Queue的種類...
    jins_1990閱讀 761評(píng)論 0 1
  • 背景 擔(dān)心了兩周的我終于輪到去醫(yī)院做胃鏡檢查了较屿!去的時(shí)候我都想好了最壞的可能(胃癌),之前在網(wǎng)上查的癥狀都很相似购啄。...
    Dely閱讀 9,239評(píng)論 21 42
  • 閨蜜從大洋彼岸回來(lái)狮含,說(shuō)是要盡盡孝心帶老爹出去玩玩曼振,正好我有空一同前往,途中要去一個(gè)海邊小城映胁,想起有個(gè)同學(xué)在那兒甲雅,就...
    黃小閑閱讀 268評(píng)論 2 2
  • 其實(shí)相對(duì)于喝咖啡 更愛(ài)聞咖啡抛人;相對(duì)于聞咖啡 更愛(ài)去咖啡館弛姜。怎么說(shuō)呢?函匕!就是 在那個(gè)氛圍中 我愿意獨(dú)處 但是有陪伴的...
    Vivian_dh閱讀 385評(píng)論 0 2
  • 對(duì)你 我確實(shí)要結(jié)束我的幻想了 或許我們根本就不是一路人吧 再見(jiàn)了 這次是真的 我重新找一條出路了 新的一天娱据,新的你...
    chde我閱讀 111評(píng)論 0 0