多線程網(wǎng)絡(luò)-2

Xmind

多線程和網(wǎng)絡(luò)2.jpg

GitBook

0.補(bǔ)充

使用Crearte函數(shù)創(chuàng)建的并發(fā)隊(duì)列和全局并發(fā)隊(duì)列的主要區(qū)別:
1.全局并發(fā)隊(duì)列在整個(gè)應(yīng)用程序中本身是默認(rèn)存在的茁影,并且對應(yīng)有高優(yōu)先級样漆、默認(rèn)優(yōu)先級、低優(yōu)先級和后臺(tái)優(yōu)先級一共四個(gè)并發(fā)隊(duì)列精续,我們只是選擇其中的一個(gè)直接拿來用。而Crearte函數(shù)是實(shí)打?qū)嵉膹念^開始去創(chuàng)建一個(gè)隊(duì)列泵三。
2.在iOS6.0之前酝碳,在GCD中凡是使用了帶Create和retain的函數(shù)在最后都需要做一次release操作。而主隊(duì)列和全局并發(fā)隊(duì)列不需要我們手動(dòng)release反粥。當(dāng)然了,在iOS6.0之后GCD已經(jīng)被納入到了ARC的內(nèi)存管理范疇中疲迂,即便是使用retain或者create函數(shù)創(chuàng)建的對象也不再需要開發(fā)人員手動(dòng)釋放才顿,我們像對待普通OC對象一樣對待GCD就OK。
3.在使用柵欄函數(shù)的時(shí)候尤蒿,蘋果官方明確規(guī)定柵欄函數(shù)只有在和使用create函數(shù)自己的創(chuàng)建的并發(fā)隊(duì)列一起使用的時(shí)候才有效(沒有給出具體原因)
4.其它區(qū)別涉及到XNU內(nèi)核的系統(tǒng)級線程編程郑气,不一一列舉。
5.給出一些參考資料(可以自行研究):

GCDAPI:https://developer.apple.com/library/ios/documentation/Performance/Reference/GCD_libdispatch_Ref/index.html#//apple_ref/c/func/dispatch_queue_create

Libdispatch版本源碼:http://www.opensource.apple.com/source/libdispatch/libdispatch-187.5/

1.單例模式

  • 1.1 概念相關(guān)

(1)單例模式

在程序運(yùn)行過程腰池,一個(gè)類只有一個(gè)實(shí)例

(2)使用場合

在整個(gè)應(yīng)用程序中尾组,共享一份資源(這份資源只需要?jiǎng)?chuàng)建初始化1次)
  • 1.2 ARC實(shí)現(xiàn)單例

(1)步驟

01 在類的內(nèi)部提供一個(gè)static修飾的全局變量
02 提供一個(gè)類方法,方便外界訪問
03 重寫+allocWithZone方法巩螃,保證永遠(yuǎn)都只為單例對象分配一次內(nèi)存空間
04 嚴(yán)謹(jǐn)起見演怎,重寫-copyWithZone方法和-MutableCopyWithZone方法

(2)相關(guān)代碼

//提供一個(gè)static修飾的全局變量匕争,強(qiáng)引用著已經(jīng)實(shí)例化的單例對象實(shí)例
static XMGTools *_instance;

//類方法避乏,返回一個(gè)單例對象
+(instancetype)shareTools
{
     //注意:這里建議使用self,而不是直接使用類名Tools(考慮繼承)

    return [[self alloc]init];
}

//保證永遠(yuǎn)只分配一次存儲(chǔ)空間
+(instancetype)allocWithZone:(struct _NSZone *)zone
{
    //使用GCD中的一次性代碼
//    static dispatch_once_t onceToken;
//    dispatch_once(&onceToken, ^{
//        _instance = [super allocWithZone:zone];
//    });

    //使用加鎖的方式,保證只分配一次存儲(chǔ)空間
    @synchronized(self) {
        if (_instance == nil) {
            _instance = [super allocWithZone:zone];
        }
    }
    return _instance;
}
/*
1. mutableCopy 創(chuàng)建一個(gè)新的可變對象甘桑,并初始化為原對象的值拍皮,新對象的引用計(jì)數(shù)為 1;
2. copy 返回一個(gè)不可變對象跑杭。分兩種情況:(1)若原對象是不可變對象铆帽,那么返回原對象,并將其引用計(jì)數(shù)加 1 德谅;(2)若原對象是可變對象爹橱,那么創(chuàng)建一個(gè)新的不可變對象,并初始化為原對象的值窄做,新對象的引用計(jì)數(shù)為 1愧驱。
*/
//讓代碼更加的嚴(yán)謹(jǐn)
-(nonnull id)copyWithZone:(nullable NSZone *)zone
{
//    return [[self class] allocWithZone:zone];
    return _instance;
}

-(nonnull id)mutableCopyWithZone:(nullable NSZone *)zone
{
    return _instance;
}

  • 1.3 MRC實(shí)現(xiàn)單例

(1)實(shí)現(xiàn)步驟

01 在類的內(nèi)部提供一個(gè)static修飾的全局變量
02 提供一個(gè)類方法慰技,方便外界訪問
03 重寫+allocWithZone方法,保證永遠(yuǎn)都只為單例對象分配一次內(nèi)存空間
04 嚴(yán)謹(jǐn)起見组砚,重寫-copyWithZone方法和-MutableCopyWithZone方法
05 重寫release方法
06 重寫retain方法
07 建議在retainCount方法中返回一個(gè)最大值

(2)配置MRC環(huán)境知識(shí)

01 注意ARC不是垃圾回收機(jī)制吻商,是編譯器特性
02 配置MRC環(huán)境:build setting ->搜索automatic ref->修改為NO

(3)相關(guān)代碼

//提供一個(gè)static修飾的全局變量,強(qiáng)引用著已經(jīng)實(shí)例化的單例對象實(shí)例
static XMGTools *_instance;

//類方法糟红,返回一個(gè)單例對象
+(instancetype)shareTools
{
     //注意:這里建議使用self,而不是直接使用類名Tools(考慮繼承)

    return [[self alloc]init];
}

//保證永遠(yuǎn)只分配一次存儲(chǔ)空間
+(instancetype)allocWithZone:(struct _NSZone *)zone
{
    //使用GCD中的一次性代碼
//    static dispatch_once_t onceToken;
//    dispatch_once(&onceToken, ^{
//        _instance = [super allocWithZone:zone];
//    });

    //使用加鎖的方式艾帐,保證只分配一次存儲(chǔ)空間
    @synchronized(self) {
        if (_instance == nil) {
            _instance = [super allocWithZone:zone];
        }
    }
    return _instance;
}

//讓代碼更加的嚴(yán)謹(jǐn)
-(nonnull id)copyWithZone:(nullable NSZone *)zone
{
//    return [[self class] allocWithZone:zone];
    return _instance;
}

-(nonnull id)mutableCopyWithZone:(nullable NSZone *)zone
{
    return _instance;
}

//在MRC環(huán)境下,如果用戶retain了一次盆偿,那么直接返回instance變量柒爸,不對引用計(jì)數(shù)器+1
//如果用戶release了一次,那么什么都不做事扭,因?yàn)閱卫J皆谡麄€(gè)程序運(yùn)行過程中都擁有且只有一份揍鸟,程序退出之后被釋放,所以不需要對引用計(jì)數(shù)器操作
-(oneway void)release
{
}

-(instancetype)retain
{
    return _instance;
}

//慣用法句旱,有經(jīng)驗(yàn)的程序員通過打印retainCount這個(gè)值可以猜到這是一個(gè)單例
-(NSUInteger)retainCount
{
    return MAXFLOAT;
}

  • 1.4 通用版本

(1)有意思的對話

01 問:寫一份單例代碼在ARC和MRC環(huán)境下都適用阳藻?
答:可以使用條件編譯來判斷當(dāng)前項(xiàng)目環(huán)境是ARC還是MRC
02 問:條件編譯的代碼呢,么么噠谈撒?
//答:條件編譯
#if __has_feature(objc_arc)
//如果是ARC腥泥,那么就執(zhí)行這里的代碼1
#else
//如果不是ARC,那么就執(zhí)行代理的代碼2
#endif
03 問:在項(xiàng)目里面往往需要實(shí)現(xiàn)很多的單例啃匿,比如下載蛔外、網(wǎng)絡(luò)請求、音樂播放等等溯乒,弱弱的問一句單例可以用繼承嗎夹厌?
答:單例是不可以用繼承的,如果想一次寫就裆悄,四處使用矛纹,那么推薦親使用帶參數(shù)的宏定義啦!
04 問:宏定義怎么弄光稼?
答:這個(gè)嘛~~回頭看一眼我的代碼咯或南,親。

(2)使用帶參數(shù)的宏完成通用版單例模式代碼

01 注意條件編譯的代碼不能包含在宏定義里面
02 宏定義的代碼只需要寫一次就好艾君,之后直接拖到項(xiàng)目中用就OK

2.NSOperation

  • 2.1 NSOperation基本使用

(1)相關(guān)概念

01 NSOperation是對GCD的包裝
02 兩個(gè)核心概念【隊(duì)列+操作】

(2)基本使用

01 NSOperation本身是抽象類采够,只能只有它的子類
02 三個(gè)子類分別是:NSBlockOperation、NSInvocationOperation以及自定義繼承自NSOperation的類
03 NSOperation和NSOperationQueue結(jié)合使用實(shí)現(xiàn)多線程并發(fā)

(3)相關(guān)代碼

//  01 NSInvocationOperation
    //1.封裝操作
    /*
     第一個(gè)參數(shù):目標(biāo)對象
     第二個(gè)參數(shù):該操作要調(diào)用的方法冰垄,最多接受一個(gè)參數(shù)
     第三個(gè)參數(shù):調(diào)用方法傳遞的參數(shù)蹬癌,如果方法不接受參數(shù),那么該值傳nil
     */
    NSInvocationOperation *operation = [[NSInvocationOperation alloc]
                                        initWithTarget:self selector:@selector(run) object:nil];

    //2.啟動(dòng)操作
    [operation start];
-------------------------------------------------
    //  02 NSBlockOperation
    //1.封裝操作
    /*
     NSBlockOperation提供了一個(gè)類方法,在該類方法中封裝操作
     */
    NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
        //在主線程中執(zhí)行
        NSLog(@"---download1--%@",[NSThread currentThread]);
    }];

    //2.追加操作逝薪,追加的操作在子線程中執(zhí)行
    [operation addExecutionBlock:^{
        NSLog(@"---download2--%@",[NSThread currentThread]);
    }];

    [operation addExecutionBlock:^{
         NSLog(@"---download3--%@",[NSThread currentThread]);
    }];

    //3.啟動(dòng)執(zhí)行操作
    [operation start];

----------------------------------------------
// 03 自定義NSOperation
    //如何封裝操作伴奥?
    //自定義的NSOperation,通過重寫內(nèi)部的main方法實(shí)現(xiàn)封裝操作
    -(void)main
    {
        NSLog(@"--main--%@",[NSThread currentThread]);
    }

    //如何使用?
    //1.實(shí)例化一個(gè)自定義操作對象
    XMGOperation *op = [[XMGOperation alloc]init];

    //2.執(zhí)行操作
    [op start];
  • 2.2 NSOperationQueue基本使用

(1)NSOperation中的兩種隊(duì)列

01 主隊(duì)列 通過mainQueue獲得翼闽,凡是放到主隊(duì)列中的任務(wù)都將在主線程執(zhí)行
02 非主隊(duì)列 直接alloc init出來的隊(duì)列拾徙。非主隊(duì)列同時(shí)具備了并發(fā)和串行的功能,通過設(shè)置最大并發(fā)數(shù)屬性來控制任務(wù)是并發(fā)執(zhí)行還是串行執(zhí)行

(2)相關(guān)代碼

//自定義NSOperation
-(void)customOperation
{
    //1.創(chuàng)建隊(duì)列
    NSOperationQueue *queue = [[NSOperationQueue alloc]init];

    //2.封裝操作
    //好處:1.信息隱蔽
    //2.代碼復(fù)用

    XMGOperation *op1 = [[XMGOperation alloc]init];
    XMGOperation *op2 = [[XMGOperation alloc]init];

    //3.添加操作到隊(duì)列中
    [queue addOperation:op1];
    [queue addOperation:op2];
}

//NSBlockOperation
- (void)block
{
    //1.創(chuàng)建隊(duì)列
    NSOperationQueue *queue = [[NSOperationQueue alloc]init];

    //2.封裝操作
    NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"1----%@",[NSThread currentThread]);
    }];

    NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"2----%@",[NSThread currentThread]);

    }];

    [op2 addExecutionBlock:^{
        NSLog(@"3----%@",[NSThread currentThread]);
    }];

    [op2 addExecutionBlock:^{
        NSLog(@"4----%@",[NSThread currentThread]);
    }];

    //3.添加操作到隊(duì)列中
    [queue addOperation:op1];
    [queue addOperation:op2];

    //補(bǔ)充:簡便方法
    [queue addOperationWithBlock:^{
        NSLog(@"5----%@",[NSThread currentThread]);
    }];

}

//NSInvocationOperation
- (void)invocation
{
    /*
     GCD中的隊(duì)列:
     串行隊(duì)列:自己創(chuàng)建的感局,主隊(duì)列
     并發(fā)隊(duì)列:自己創(chuàng)建的尼啡,全局并發(fā)隊(duì)列

     NSOperationQueue
     主隊(duì)列:[NSOperationQueue mainqueue];凡事放在主隊(duì)列中的操作都在主線程中執(zhí)行
     非主隊(duì)列:[[NSOperationQueue alloc]init],并發(fā)和串行询微,默認(rèn)是并發(fā)執(zhí)行的
     */

    //1.創(chuàng)建隊(duì)列
    NSOperationQueue *queue = [[NSOperationQueue alloc]init];

    //2.封裝操作
    NSInvocationOperation *op1 = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(download1) object:nil];

    NSInvocationOperation *op2 = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(download2) object:nil];


    NSInvocationOperation *op3 = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(download3) object:nil];


    //3.把封裝好的操作添加到隊(duì)列中
    [queue addOperation:op1];//[op1 start]
    [queue addOperation:op2];
    [queue addOperation:op3];
}

  • 2.3 NSOperation其它用法

(1)設(shè)置最大并發(fā)數(shù)【控制任務(wù)并發(fā)和串行】

//1.創(chuàng)建隊(duì)列
    NSOperationQueue *queue = [[NSOperationQueue alloc]init];

    //2.設(shè)置最大并發(fā)數(shù)
    //注意點(diǎn):該屬性需要在任務(wù)添加到隊(duì)列中之前進(jìn)行設(shè)置
    //該屬性控制隊(duì)列是串行執(zhí)行還是并發(fā)執(zhí)行
    //如果最大并發(fā)數(shù)等于1崖瞭,那么該隊(duì)列是串行的,如果大于1那么是并行的
    //系統(tǒng)的最大并發(fā)數(shù)有個(gè)默認(rèn)的值撑毛,為-1书聚,如果該屬性設(shè)置為0,那么不會(huì)執(zhí)行任何任務(wù)
    queue.maxConcurrentOperationCount = 2;

(2)暫停和恢復(fù)以及取消

    //設(shè)置暫停和恢復(fù)
    //suspended設(shè)置為YES表示暫停藻雌,suspended設(shè)置為NO表示恢復(fù)
    //暫停表示不繼續(xù)執(zhí)行隊(duì)列中的下一個(gè)任務(wù)雌续,暫停操作是可以恢復(fù)的
    if (self.queue.isSuspended) {
        self.queue.suspended = NO;
    }else
    {
        self.queue.suspended = YES;
    }

    //取消隊(duì)列里面的所有操作
    //取消之后,當(dāng)前正在執(zhí)行的操作的下一個(gè)操作將不再執(zhí)行胯杭,而且永遠(yuǎn)都不在執(zhí)行驯杜,就像后面的所有任務(wù)都從隊(duì)列里面移除了一樣
    //取消操作是不可以恢復(fù)的
    [self.queue cancelAllOperations];

---------自定義NSOperation取消操作--------------------------
-(void)main
{
    //耗時(shí)操作1
    for (int i = 0; i<1000; i++) {
        NSLog(@"任務(wù)1-%d--%@",i,[NSThread currentThread]);
    }
    NSLog(@"+++++++++++++++++++++++++++++++++");

    //蘋果官方建議,每當(dāng)執(zhí)行完一次耗時(shí)操作之后做个,就查看一下當(dāng)前隊(duì)列是否為取消狀態(tài)鸽心,如果是,那么就直接退出
    //好處是可以提高程序的性能
    if (self.isCancelled) {
        return;
    }

    //耗時(shí)操作2
    for (int i = 0; i<1000; i++) {
        NSLog(@"任務(wù)1-%d--%@",i,[NSThread currentThread]);
    }

    NSLog(@"+++++++++++++++++++++++++++++++++");
}
  • 2.4 NSOperation實(shí)現(xiàn)線程間通信

(1)開子線程下載圖片

 //1.創(chuàng)建隊(duì)列
    NSOperationQueue *queue = [[NSOperationQueue alloc]init];

    //2.使用簡便方法封裝操作并添加到隊(duì)列中
    [queue addOperationWithBlock:^{

        //3.在該block中下載圖片
        NSURL *url = [NSURL URLWithString:@"http://news.51sheyuan.com/uploads/allimg/111001/133442IB-2.jpg"];
        NSData *data = [NSData dataWithContentsOfURL:url];
        UIImage *image = [UIImage imageWithData:data];
        NSLog(@"下載圖片操作--%@",[NSThread currentThread]);

        //4.回到主線程刷新UI
        [[NSOperationQueue mainQueue] addOperationWithBlock:^{
            self.imageView.image = image;
            NSLog(@"刷新UI操作---%@",[NSThread currentThread]);
        }];
    }];

(2)下載多張圖片合成綜合案例(設(shè)置操作依賴)

//02 綜合案例
- (void)download2
{
    NSLog(@"----");
    //1.創(chuàng)建隊(duì)列
    NSOperationQueue *queue = [[NSOperationQueue alloc]init];

    //2.封裝操作下載圖片1
    NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{

        NSURL *url = [NSURL URLWithString:@"http://h.hiphotos.baidu.com/zhidao/pic/item/6a63f6246b600c3320b14bb3184c510fd8f9a185.jpg"];
        NSData *data = [NSData dataWithContentsOfURL:url];

        //拿到圖片數(shù)據(jù)
        self.image1 = [UIImage imageWithData:data];
    }];


    //3.封裝操作下載圖片2
    NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{
        NSURL *url = [NSURL URLWithString:@"http://pic.58pic.com/58pic/13/87/82/27Q58PICYje_1024.jpg"];
        NSData *data = [NSData dataWithContentsOfURL:url];

        //拿到圖片數(shù)據(jù)
        self.image2 = [UIImage imageWithData:data];
    }];

    //4.合成圖片
    NSBlockOperation *combine = [NSBlockOperation blockOperationWithBlock:^{

        //4.1 開啟圖形上下文
        UIGraphicsBeginImageContext(CGSizeMake(200, 200));

        //4.2 畫image1
        [self.image1 drawInRect:CGRectMake(0, 0, 200, 100)];

        //4.3 畫image2
        [self.image2 drawInRect:CGRectMake(0, 100, 200, 100)];

        //4.4 根據(jù)圖形上下文拿到圖片數(shù)據(jù)
        UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
//        NSLog(@"%@",image);

        //4.5 關(guān)閉圖形上下文
        UIGraphicsEndImageContext();

        //7.回到主線程刷新UI
        [[NSOperationQueue mainQueue]addOperationWithBlock:^{
            self.imageView.image = image;
            NSLog(@"刷新UI---%@",[NSThread currentThread]);
        }];

    }];

    //5.設(shè)置操作依賴
    [combine addDependency:op1];
    [combine addDependency:op2];

    //6.添加操作到隊(duì)列中執(zhí)行
    [queue addOperation:op1];
    [queue addOperation:op2];
    [queue addOperation:combine];
    }

3.多圖下載綜合示例程序

(1)涉及知識(shí)點(diǎn)

     01 字典轉(zhuǎn)模型
     02 存儲(chǔ)數(shù)據(jù)到沙盒居暖,從沙盒中加載數(shù)據(jù)
     03 占位圖片的設(shè)置(cell的刷新問題)
     04 如何進(jìn)行內(nèi)存緩存(使用NSDictionary)
     05 在程序開發(fā)過程中的一些容錯(cuò)處理
     06 如何刷新tableView的指定行(解決數(shù)據(jù)錯(cuò)亂問題)
     07 NSOperation以及線程間通信相關(guān)知識(shí)

4.第三方框架

(1)SDWebImage基本使用

    01 設(shè)置imageView的圖片
    [cell.imageView sd_setImageWithURL:[NSURL URLWithString:app.icon] placeholderImage:[UIImage imageNamed:@"placehoder"]];

    02 設(shè)置圖片并計(jì)算下載進(jìn)度
       //下載并設(shè)置圖片
    /*
     第一個(gè)參數(shù):要下載圖片的url地址
     第二個(gè)參數(shù):設(shè)置該imageView的占位圖片
     第三個(gè)參數(shù):傳一個(gè)枚舉值顽频,告訴程序你下載圖片的策略是什么
     第一個(gè)block塊:獲取當(dāng)前圖片數(shù)據(jù)的下載進(jìn)度
         receivedSize:已經(jīng)下載完成的數(shù)據(jù)大小
         expectedSize:該文件的數(shù)據(jù)總大小
     第二個(gè)block塊:當(dāng)圖片下載完成之后執(zhí)行該block中的代碼
         image:下載得到的圖片數(shù)據(jù)
         error:下載出現(xiàn)的錯(cuò)誤信息
         SDImageCacheType:圖片的緩存策略(不緩存,內(nèi)存緩存太闺,沙盒緩存)
         imageURL:下載的圖片的url地址
     */
    [cell.imageView sd_setImageWithURL:[NSURL URLWithString:app.icon] placeholderImage:[UIImage imageNamed:@"placehoder"] options:SDWebImageRetryFailed progress:^(NSInteger receivedSize, NSInteger expectedSize) {

        //計(jì)算當(dāng)前圖片的下載進(jìn)度
        NSLog(@"%.2f",1.0 *receivedSize / expectedSize);

    } completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {

    }];

    03 系統(tǒng)級內(nèi)存警告如何處理(面試)
    //取消當(dāng)前正在進(jìn)行的所有下載操作
    [[SDWebImageManager sharedManager] cancelAll];

    //清除緩存數(shù)據(jù)(面試)
    //cleanDisk:刪除過期的文件數(shù)據(jù)糯景,計(jì)算當(dāng)前未過期的已經(jīng)下載的文件數(shù)據(jù)的大小,如果發(fā)現(xiàn)該數(shù)據(jù)大小大于我們設(shè)置的最大緩存數(shù)據(jù)大小跟束,那么程序內(nèi)部會(huì)按照按文件數(shù)據(jù)緩存的時(shí)間從遠(yuǎn)到近刪除莺奸,知道小于最大緩存數(shù)據(jù)為止丑孩。

    //clearMemory:直接刪除文件冀宴,重新創(chuàng)建新的文件夾
    //[[SDWebImageManager sharedManager].imageCache cleanDisk];
    [[SDWebImageManager sharedManager].imageCache clearMemory];

    04 SDWebImage默認(rèn)的緩存時(shí)間是1周
    05 如何播放gif圖片
    /*
    5-1 把用戶傳入的gif圖片->NSData
    5-2 根據(jù)該Data創(chuàng)建一個(gè)圖片數(shù)據(jù)源(NSData->CFImageSourceRef)
    5-3 計(jì)算該數(shù)據(jù)源中一共有多少幀,把每一幀數(shù)據(jù)取出來放到圖片數(shù)組中
    5-4 根據(jù)得到的數(shù)組+計(jì)算的動(dòng)畫時(shí)間-》可動(dòng)畫的image
    [UIImage animatedImageWithImages:images duration:duration];
    */

    06 如何判斷當(dāng)前圖片類型
    + (NSString *)sd_contentTypeForImageData:(NSData *)data;


(2)SDWebImage內(nèi)部結(jié)構(gòu)


1.png

PPT

GCD

Snip20170320_35.png
Snip20170320_36.png
Snip20170320_37.png
Snip20170320_38.png
Snip20170320_39.png
Snip20170320_40.png
Snip20170320_41.png
Snip20170320_42.png
Snip20170320_43.png
Snip20170320_44.png
Snip20170320_45.png
Snip20170320_46.png
Snip20170320_47.png
Snip20170320_48.png
Snip20170320_49.png
Snip20170320_50.png
Snip20170320_51.png
Snip20170320_52.png
Snip20170320_53.png

NSOperation

Snip20170320_54.png
Snip20170320_55.png
Snip20170320_56.png
Snip20170320_57.png
Snip20170320_58.png
Snip20170320_59.png
Snip20170320_60.png
Snip20170320_61.png
Snip20170320_62.png
Snip20170320_63.png
Snip20170320_64.png
Snip20170320_65.png
Snip20170320_66.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末温学,一起剝皮案震驚了整個(gè)濱河市略贮,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖逃延,帶你破解...
    沈念sama閱讀 217,907評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件览妖,死亡現(xiàn)場離奇詭異,居然都是意外死亡揽祥,警方通過查閱死者的電腦和手機(jī)讽膏,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,987評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來拄丰,“玉大人府树,你說我怎么就攤上這事×习矗” “怎么了奄侠?”我有些...
    開封第一講書人閱讀 164,298評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長载矿。 經(jīng)常有香客問我垄潮,道長,這世上最難降的妖魔是什么闷盔? 我笑而不...
    開封第一講書人閱讀 58,586評論 1 293
  • 正文 為了忘掉前任弯洗,我火速辦了婚禮,結(jié)果婚禮上逢勾,老公的妹妹穿的比我還像新娘涂召。我一直安慰自己,他們只是感情好敏沉,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,633評論 6 392
  • 文/花漫 我一把揭開白布果正。 她就那樣靜靜地躺著,像睡著了一般盟迟。 火紅的嫁衣襯著肌膚如雪赋访。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,488評論 1 302
  • 那天牵啦,我揣著相機(jī)與錄音茎活,去河邊找鬼。 笑死辖众,一個(gè)胖子當(dāng)著我的面吹牛卓起,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播凹炸,決...
    沈念sama閱讀 40,275評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼戏阅,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了啤它?” 一聲冷哼從身側(cè)響起奕筐,我...
    開封第一講書人閱讀 39,176評論 0 276
  • 序言:老撾萬榮一對情侶失蹤舱痘,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后离赫,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體芭逝,經(jīng)...
    沈念sama閱讀 45,619評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,819評論 3 336
  • 正文 我和宋清朗相戀三年渊胸,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了旬盯。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,932評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡翎猛,死狀恐怖瓢捉,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情办成,我是刑警寧澤泡态,帶...
    沈念sama閱讀 35,655評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站迂卢,受9級特大地震影響某弦,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜而克,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,265評論 3 329
  • 文/蒙蒙 一靶壮、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧员萍,春花似錦腾降、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,871評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至筋帖,卻和暖如春奸晴,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背日麸。 一陣腳步聲響...
    開封第一講書人閱讀 32,994評論 1 269
  • 我被黑心中介騙來泰國打工寄啼, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人代箭。 一個(gè)月前我還...
    沈念sama閱讀 48,095評論 3 370
  • 正文 我出身青樓墩划,卻偏偏與公主長得像,于是被迫代替她去往敵國和親嗡综。 傳聞我的和親對象是個(gè)殘疾皇子乙帮,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,884評論 2 354

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

  • 轉(zhuǎn)載:[IOS 多線程 & 網(wǎng)絡(luò) - 2.5] – 小文件上傳 A.文件上傳 思路: 發(fā)送文件數(shù)據(jù)給服務(wù)器 使用p...
    路上的Acmen閱讀 573評論 2 0
  • *面試心聲:其實(shí)這些題本人都沒怎么背,但是在上海 兩周半 面了大約10家 收到差不多3個(gè)offer,總結(jié)起來就是把...
    Dove_iOS閱讀 27,140評論 30 470
  • Object C中創(chuàng)建線程的方法是什么?如果在主線程中執(zhí)行代碼蛤高,方法是什么蚣旱?如果想延時(shí)執(zhí)行代碼碑幅、方法又是什么戴陡? 1...
    AlanGe閱讀 1,739評論 0 17
  • 1.單例模式 1.1 概念相關(guān) (1)單例模式 在程序運(yùn)行過程塞绿,一個(gè)類只有一個(gè)實(shí)例 (2)使用場合 在整個(gè)應(yīng)用程序...
    怎樣m閱讀 258評論 0 0
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,127評論 25 707