iOS開發(fā)3年只用5分鐘搞定面試官

序言

假輿馬者呵俏,非利足也,而致千里滔灶;假舟楫者普碎,非能水也,而絕江河录平。君子生非異也麻车,善假于物也缀皱。
我們曾借白茶清歡等一個人,曾借花開花落嘆寵辱不驚动猬。
程序(Program)是一個可以運行的文件, 一個程序至少有一個進程,一個進程至少有一個線程,即主線程

正文

程序(Program)是一個可以運行的文件, 一個程序至少有一個進程,一個進程至少有一個線程,即主線程
進程:正在進行的程序被稱為進程,負責程序運行的內(nèi)存分配,每個進程都有自己的獨立虛擬內(nèi)存空間.一個程序的一次運行啤斗,在執(zhí)行過程中擁有獨立的內(nèi)存單元,而多個線程共享一塊內(nèi)存
什么是線程:線程是進程中的基本單元(可執(zhí)行的代碼段),線程可以并發(fā)運行赁咙,提高執(zhí)行效率
創(chuàng)建線程的目的:就是為了開啟一條新的可執(zhí)行的代碼段钮莲,與主線程中的代碼實現(xiàn)同時運行,防止界面假死,是實現(xiàn)異步的技術(shù)的主要手段,比如網(wǎng)絡(luò)異步下載

一 Runloop知識點補充

1 在模擬器中拖拽UITextView的時候?qū)unLoop模式的影響
1.1 performSelector: 方法

—-對該方法的解釋: 該方法運行的時候回受到runloop運行模式的影響,默認設(shè)置為defaulmode,當拖拽的時候,runloop切換模式,所以不執(zhí)行

代碼塊和解釋一:

//由于該方法設(shè)置了RunLoop的運行模式為兩種,當用戶滑動UITextView的時候RunLoop切換模式并且繼續(xù)執(zhí)行,所以能設(shè)置出圖片
    [self.imageView1 performSelector:@selector(setImage:) withObject:[UIImage imageNamed:@"/Users/xiaofeng/Desktop/Snip20160319_18.png"] afterDelay:5.0 inModes:@[UITrackingRunLoopMode,NSDefaultRunLoopMode]];

代碼塊和解釋二:

//該方法的執(zhí)行會受到外界的影響,當用戶滑動UITextView的時候,并不會經(jīng)過2秒設(shè)置圖片,runloop運行的模式是默認的模式,當用戶滑動UITextView的時候,切換了模式,所以不會設(shè)置圖片
    [self.imageView1 performSelector:@selector(setImage:) withObject:[UIImage imageNamed:@"/Users/xiaofeng/Desktop/Snip20160319_15.png"] afterDelay:2.0];

2 問題:怎么能讓一個線程一直活著,然后在特定的情況下,讓線程跳轉(zhuǎn)任務(wù)

二 常駐線程

3 保證線程不死的方法:創(chuàng)建一個RunLoop循環(huán);然后設(shè)置數(shù)據(jù)源或者定時器

3.1 第一種方法:開啟一個死循環(huán)—>比如while死循環(huán),保持線程不死亡,這樣雖然能保證線程不死,但是不能保證線程去執(zhí)行其它的任務(wù)(不可取)

3.2 第二種方法:開啟一個RunLoop循環(huán),也可以保證讓線程不死,但是開啟了需要手動執(zhí)行,并且需要設(shè)置運行模式,否則單單只是開啟了RunLoop循環(huán),并沒有設(shè)置模式的話,RunLoop開啟了就直接退出,并不會一直往下執(zhí)行(開啟RunLoop需要完成指定的三個步驟)

4 需求:當點擊創(chuàng)建線程的按鈕的時候,開始創(chuàng)建一條線程,然后點擊讓子線程開始干其他的工作的時候,子線程開始執(zhí)行其他工作

1 創(chuàng)建子線程按鈕:

#pragma mark - 創(chuàng)建子線程按鈕
- (IBAction)creatBtnClick:(id)sender
{
    //創(chuàng)建子線程
    NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(task) object:nil];

    [thread start];
    //如果不加入這句代碼,線程在執(zhí)行完task方法之后就會立刻被釋放,這里寫這句代碼目的就是保證線程不死,能繼續(xù)執(zhí)行其他的任務(wù)
    self.thread = thread;
}

創(chuàng)建子線程按鈕中的方法實現(xiàn): 在task方法中我們只要求打印當前線程就行.

讓子線程開始繼續(xù)工作:

#pragma mark - 讓線程繼續(xù)工作

- (IBAction)goOnBtnClick:(id)sender
{
    [self performSelector:@selector(task2) onThread:self.thread withObject:nil waitUntilDone:YES];
}

問題:如果就這樣運行的話,就會報錯.
報錯原因:雖然上面在創(chuàng)建子線程中已經(jīng)寫了一句self.thread = thread保證子線程不會被釋放,但是由于沒有開啟runloop循環(huán),那么子線程其實是處于死亡狀態(tài),所以當在點擊讓子線程繼續(xù)工作的話就會報錯.
解決辦法:創(chuàng)建子線程的RunLoop,讓子線程一直在運行,然后通過設(shè)置在方法里面的調(diào)用其它的需要子線程工作的方法,讓子線程去工作

#pragma mark - 工作在線程中的任務(wù)
- (void)task
{
    NSLog(@"1------%@",[NSThread currentThread]);
    //創(chuàng)建RunLoop
    NSRunLoop *runLoop = [NSRunLoop currentRunLoop];

    //創(chuàng)建timer(這種方法需要手動設(shè)置模式)
    NSTimer *timer = [NSTimer timerWithTimeInterval:2.0 target:self selector:@selector(timeRun) userInfo:nil repeats:YES];
//
//    //添加到runloop中,并設(shè)置模式
    [runLoop addTimer:timer forMode:NSDefaultRunLoopMode];
//    [runLoop addPort:[NSPort port] forMode:NSDefaultRunLoopMode];

    //開啟runloop

    [runLoop run];
    NSLog(@"%s-------2-----%@",__func__,[NSThread currentThread]);
}

注意:上面創(chuàng)建時鐘的代碼和添加時鐘到runloop中的代碼可以寫成下面一句,同樣也能保證線程不處于死亡狀態(tài)

[runLoop addPort:[NSPort port] forMode:NSDefaultRunLoopMode];

5 RunLoop的自動釋放池

第一次創(chuàng)建 RunLoop啟動的時候
最后一次 RunLoop退出的時候
其它時間的創(chuàng)建和銷毀:當RunLoop即將休眠的時候會把之前的自動釋放池銷毀,重新創(chuàng)建一個新的
6 RunLoop在網(wǎng)絡(luò)中的應(yīng)用(直接看代碼就可以)

- (void)delegate1
{
    //確定請求路徑
    NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/login?username=520it&pwd=520it&type=JSON"];
    //創(chuàng)建可變的請求對象
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    //設(shè)置代理
    NSURLConnection *connention = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:YES];

    //加入該段代碼可以改變代理方法執(zhí)行的線程,默認是在主線程中執(zhí)行,但是加入該段代碼之后,代理方法會在子線程中執(zhí)行
    [connention setDelegateQueue:[[NSOperationQueue alloc] init]];

    //開始發(fā)送請求
    //1)該方法內(nèi)部會吧connention對象作為一個source添加到runloop中,并且制定運行模式為默認
    //2)如果發(fā)現(xiàn)當前的runloop不存在,那么該方法內(nèi)部會自動的創(chuàng)建并開啟當前子線程的runloop
    [connention start];

三 網(wǎng)絡(luò)
1 GET和POST對比:

GET請求參數(shù)直接跟在URL后面(?)
POST請求參數(shù)是在請求體里面

2 HTTP基本通信過程:客戶端—>請求—->服務(wù)器;服務(wù)器—>響應(yīng)—->客戶端

具體的操作步驟:
2.1 確定請求路徑
2.2 獲取主機名
2.3 DNS域名解析
2.4 獲得端口號
2.5 鏈接到120.25.226.186的端口80
2.6 發(fā)送一個HTTP GET請求
2.7 接收服務(wù)器的響應(yīng)
2.8 關(guān)閉鏈接

3 請求和響應(yīng)

請求:
請求頭:包含了客戶端的環(huán)境描述,客戶端請求信息等
請求體:客戶端發(fā)給服務(wù)器的具體數(shù)據(jù),比如文件數(shù)據(jù)(POST請求才會有)
響應(yīng):
響應(yīng)頭:包含了對服務(wù)器的描述,對返回數(shù)據(jù)的描述
響應(yīng)體:服務(wù)器返回給客戶端的具體數(shù)據(jù),比如文件數(shù)據(jù)
如圖:

4 HTTP請求

HTTP請求的第三方框架:ASIHttpRequest(已經(jīng)棄用);AFNetworking(主用);MKNetworking

蘋果自帶的:

NSURLConnection:用法簡單,最古老最經(jīng)典最直接的一種方案
NSURLSession:功能比NSURLConnection更強大,蘋果目前比較推薦的使用技術(shù)(重要)
CFNetwork:NSURL*的底層,純C語言

第三方框架:(企業(yè)開發(fā)基本使用的是第三方框架)

ASIHttpRequest:外號”HTTP終結(jié)者”,功能極其強大,可惜已經(jīng)停止更新了

AFNetworking:簡單易用,提供了基本夠用的常用功能,維護和使用者多(重要)

MKNsetworking:簡單易用,產(chǎn)生三哥的故鄉(xiāng)印度,維護和使用者少

四 GET方式

1 概念:發(fā)送網(wǎng)絡(luò)請求的兩種方式,主要區(qū)別上面已經(jīng)有寫
2 發(fā)送同步請求
具體步驟:

1> 確定請求路徑
2> 創(chuàng)建請求對象
3> 發(fā)送請求
4 > 解析接收數(shù)據(jù)
#pragma mark - 發(fā)送同步請求
- (void)sendSync
{
    //確定請求路徑
    NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/login?username=520it&pwd=520it&type=JSON"];

    //創(chuàng)建請求對象
    NSURLRequest *request = [NSURLRequest requestWithURL:url];

    //初始化響應(yīng)頭信息(設(shè)置為空)
    NSHTTPURLResponse *response = nil;
    //初始化錯誤信息
    NSError *error = nil;

    //發(fā)送請求
    /**
     *  第一個參數(shù):請求對象
     *
     *  第二個參數(shù):響應(yīng)頭信息(傳入的是地址)
     *
     *  第三個參數(shù):錯誤信息(如果發(fā)送請求失敗,那么error就有值)(傳入的是地址)
     */
    NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];

    //解析返回的響應(yīng)數(shù)據(jù)
    NSLog(@"%@",[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
}

3 發(fā)送異步請求

注意:同步請求和異步請求的主要區(qū)別就是發(fā)送請求中的方法不同.

#pragma mark - 發(fā)送異步請求

- (void)sendAsync
{
    //確定請求路徑
    NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/login?username=520it&pwd=520it&type=JSON"];

    //創(chuàng)建請求對象
    NSURLRequest *resquest = [NSURLRequest requestWithURL:url];

    //發(fā)送請求
    /**
     *  參數(shù)一:請求對象
     *
     *  參數(shù)二:隊列(作用在completionHandler上面)
     *
     *  參數(shù)三:響應(yīng)的信息(響應(yīng)頭;響應(yīng)的數(shù)據(jù))
                response 響應(yīng)頭信息
                data     響應(yīng)體信息
                connectionError 錯誤信息
     */
    [NSURLConnection sendAsynchronousRequest:resquest queue:[[NSOperationQueue alloc] init] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {
        //解析數(shù)據(jù)
        NSLog(@"%@",[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
    }];
}

4 用代理的方法發(fā)送網(wǎng)絡(luò)請求

注意:需要遵守協(xié)議:

<NSURLConnectionDataDelegate>

代理方法發(fā)送,里面包括了設(shè)置代理的三種方式

#pragma mark - 代理方法發(fā)送請求
- (void)sendAsyncDelegate
{
    //確定請求路徑
    NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/login?username=520it&pwd=520it&type=JSON"];

    //創(chuàng)建請求對象
    NSURLRequest *request = [NSURLRequest requestWithURL:url];

    //設(shè)置代理
    //第一種設(shè)置代理:
    [NSURLConnection connectionWithRequest:request delegate:self];
    //第二種設(shè)置代理:
    NSURLConnection *connecttion1 = [[NSURLConnection alloc] initWithRequest:request delegate:self];
    //第三種設(shè)置代理:
    NSURLConnection *connecttion2 = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:YES];

    [connecttion2 start];  
}

實現(xiàn)代理中的方法

#pragma mark - 代理方法
//請求失敗的時候調(diào)用
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
    NSLog(@"%s------%@",__func__,[NSThread currentThread]);
}
//接收響應(yīng)頭信息
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
    NSLog(@"%s------%@",__func__,[NSThread currentThread]);

    //創(chuàng)建接收可變的二進制數(shù)據(jù)
    self.responseData = [NSMutableData data];

}
//接收響應(yīng)體(如果數(shù)據(jù)足夠大那么這個方法會調(diào)用多次)
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
    NSLog(@"%s------%@",__func__,[NSThread currentThread]);
    //拼接二進制數(shù)據(jù)
    [self.responseData appendData:data];
}

//接收完成(不管成功還是失敗)
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    NSLog(@"%s------%@",__func__,[NSThread currentThread]);

    //解析數(shù)據(jù)
    NSLog(@"%@",[[NSString alloc] initWithData:self.responseData encoding:NSUTF8StringEncoding]);
}

五 POST方式
1 直接看代碼,上面都標明了

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    //創(chuàng)建請求路徑
    NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/login"];
    //創(chuàng)建可變的請求對象
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];

    //修改請求方式
    request.HTTPMethod = @"POST";

    //設(shè)置請求超時
    request.timeoutInterval = 10;

    NSURLResponse *response = nil;

    NSError *error = nil;

    //設(shè)置請求頭信息
    [request setValue:@"jjjj" forHTTPHeaderField:@"uuuuu"];

    //設(shè)置請求體(參數(shù))
    request.HTTPBody = [@"username=520it&pwd=520it&type=JSON" dataUsingEncoding:NSUTF8StringEncoding];

    //第一種方法:發(fā)送請求(異步請求)
    [NSURLConnection sendAsynchronousRequest:request queue:[[NSOperationQueue alloc] init] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {
        //解析數(shù)據(jù)
        if (connectionError == nil) {
            NSLog(@"%@",[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);

        }else{
            NSLog(@"%@",connectionError);
        }
    }];

    //第二種方法:發(fā)送請求(同步請求)
    NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
    //解析數(shù)據(jù)
    NSLog(@"%@",[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
}

六 中文轉(zhuǎn)碼
1 判斷需不需要轉(zhuǎn)碼操作:看請求路徑是否含有中文,含有的話,就需要轉(zhuǎn)碼
2 設(shè)置代理的多一個參數(shù)的方法中:如果設(shè)置的為NO,那么手動開啟的時候,底層start會把線程加入到runloop中,但是如果設(shè)置的為yes,那么和沒有參數(shù)的時候一樣,需要手動創(chuàng)建runloop.
GET轉(zhuǎn)碼:

#pragma mark - GET轉(zhuǎn)碼
- (void)get
{
    //確定請求字符串
    NSString *strurl = @"http://120.25.226.186:32812/login2?username=(需要轉(zhuǎn)的漢字)&pwd=520it&type=JSON";

    //轉(zhuǎn)碼
    strurl = [strurl stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

    //確定路徑
    NSURL *url = [NSURL URLWithString:strurl];

    //創(chuàng)建可變的請求對象
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];

    //發(fā)送請求--->GET請求
    [NSURLConnection sendAsynchronousRequest:request queue:[[NSOperationQueue alloc] init] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {
       //解析數(shù)據(jù)
        if (connectionError == nil) {
            NSLog(@"%@",[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
        }else{
            NSLog(@"%@",connectionError);
        }
    }];
}

POST轉(zhuǎn)碼:

#pragma mark - POST轉(zhuǎn)碼
- (void)post
{
    //確定請求路徑的字符串
    NSString *urlstr = @"http://120.25.226.186:32812/login2";

    //確定url
    NSURL *url = [NSURL URLWithString:urlstr];

    //創(chuàng)建請求對象
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];

    //轉(zhuǎn)為POST格式
    request.HTTPMethod = @"POST";
    //轉(zhuǎn)碼
    request.HTTPBody = [@"username=(需要轉(zhuǎn)的漢字)&pwd=520it&type=JSON" dataUsingEncoding:NSUTF8StringEncoding ];
    NSURLResponse *response = nil;
    NSError *error = nil;

    //發(fā)送請求(同步請求)
    NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
    //解析數(shù)據(jù)
    NSLog(@"%@",[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);

    //發(fā)送請求(異步請求)
    [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {
        //解析數(shù)據(jù)
        if (connectionError == nil) {
            NSLog(@"%@",[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
        }else{
            NSLog(@"%@",connectionError);
        }

    }];    
}

七 NSURLSession簡單使用
1 NSURLSession —->GET用法:

- (void)get
{
    //確定請求路徑
    NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/login?username=520it&pwd=520it&type=JSON"];
    //創(chuàng)建請求對象
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url ];
    //獲取會話對象(是一個單例)
    NSURLSession *session = [NSURLSession sharedSession];

    //根據(jù)會話對象創(chuàng)建task
    /**
     *  參數(shù)一:請求對象
     *
     *  參數(shù)二:響應(yīng)頭response信息;響應(yīng)體data信息;error錯誤信息
     *
     *
     */
    NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        //解析數(shù)據(jù)
        NSLog(@"%@",[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
        //該block塊是在子線程中調(diào)用
         NSLog(@"%@",[NSThread currentThread]);
    } ];

    //執(zhí)行task
    [dataTask resume];
}

2 GET用法二:

- (void)get1
{
    //確定請求路徑
    NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/login?username=520it&pwd=520it&type=JSON"];

    //創(chuàng)建請求對象
//    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];

    //創(chuàng)建會話對象
    NSURLSession *session = [NSURLSession sharedSession];

    //根據(jù)會話對象創(chuàng)建task
    NSURLSessionDataTask *dataTask = [session dataTaskWithURL:url completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        NSLog(@"%@",[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
        //該block塊是在子線程中調(diào)用
         NSLog(@"%@",[NSThread currentThread]);
    }];
    //開啟task
    [dataTask resume];
}

3 GET1和GET2的區(qū)別是根據(jù)會話對象創(chuàng)建task不同,其實用法還是一樣的.
4 POST用法:

- (void)post
{
    //確定請求路徑
    NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/login"];

    //創(chuàng)建可變的請求對象
    NSMutableURLRequest *resquest = [NSMutableURLRequest requestWithURL:url];

    //轉(zhuǎn)換格式
    resquest.HTTPMethod = @"POST";

    //設(shè)置請求體信息
    resquest.HTTPBody = [@"username=520it&pwd=520it&type=JSON" dataUsingEncoding:NSUTF8StringEncoding];

    //獲取會話
    NSURLSession *session = [NSURLSession sharedSession];

    //用會話對象創(chuàng)建task
    NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:resquest completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {

        //解析數(shù)據(jù)
        if (error == nil) {
            NSLog(@"%@",[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
        }else{
            NSLog(@"%@",error);
        }
        //該block塊是在子線程中調(diào)用
        NSLog(@"%@",[NSThread currentThread]);
    }];

    //執(zhí)行task任務(wù)   resume------>恢復(fù)
    [dataTask resume];
}

八 NSURLSession的代理方法
1 主方法(在里面設(shè)置代理)

- (void)sessionGet
{
    //確定請求路徑
    NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/login?username=520it&pwd=520it&type=JSON"];
    //創(chuàng)建可變的請求對象
    NSURLRequest *request = [NSURLRequest requestWithURL:url];

    //獲取會話(delegateQueue:決定了代理的任務(wù)是在子線程還是主線程中執(zhí)行的)
    NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]];

    //創(chuàng)建task
    NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request];
    //執(zhí)行task任務(wù)
    [dataTask resume];

}

2 代理方法

注意: 此代理方法要特別的注意第一個代理方法,因為需要回調(diào)告訴系統(tǒng)怎么樣處理服務(wù)器返回的數(shù)據(jù),如果沒有寫的話,后面兩個代理方法是不會調(diào)用的,因為completionHandler并沒有告訴系統(tǒng),服務(wù)器的數(shù)據(jù)怎么處理.

#pragma mark - 代理方法
//接收響應(yīng)
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler
{
    NSLog(@"%s-------%@",__func__,[NSThread currentThread]);

    self.data = [NSMutableData data];
    //在該方法中需要通過completionHandler回調(diào)告訴系統(tǒng)應(yīng)該如何處理服務(wù)器返回的數(shù)據(jù)
    completionHandler(NSURLSessionResponseAllow);
}
//接收到二進制數(shù)據(jù)(如果數(shù)據(jù)量大會調(diào)用多次)
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data
{

    NSLog(@"%s-----%@",__func__,[NSThread currentThread]);
    //拼接數(shù)據(jù)
    [self.data appendData:data];

}
//完成或者失敗的時候調(diào)用
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
{
    NSLog(@"%s------%@",__func__,[[NSString alloc] initWithData:self.data encoding:NSUTF8StringEncoding]);
    NSLog(@"%@",[NSThread currentThread]);
}
總結(jié)

感謝你的閱讀,小編這也有一本跳槽最全攻略和面試題集需要的可以進小編的群763164022小編會分享給大家彼水。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末崔拥,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子凤覆,更是在濱河造成了極大的恐慌链瓦,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件盯桦,死亡現(xiàn)場離奇詭異慈俯,居然都是意外死亡,警方通過查閱死者的電腦和手機拥峦,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進店門肥卡,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人事镣,你說我怎么就攤上這事【疚福” “怎么了璃哟?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長喊递。 經(jīng)常有香客問我随闪,道長,這世上最難降的妖魔是什么骚勘? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任铐伴,我火速辦了婚禮,結(jié)果婚禮上俏讹,老公的妹妹穿的比我還像新娘当宴。我一直安慰自己,他們只是感情好泽疆,可當我...
    茶點故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布户矢。 她就那樣靜靜地躺著,像睡著了一般殉疼。 火紅的嫁衣襯著肌膚如雪梯浪。 梳的紋絲不亂的頭發(fā)上捌年,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天,我揣著相機與錄音挂洛,去河邊找鬼礼预。 笑死,一個胖子當著我的面吹牛虏劲,可吹牛的內(nèi)容都是我干的托酸。 我是一名探鬼主播,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼伙单,長吁一口氣:“原來是場噩夢啊……” “哼获高!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起吻育,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤念秧,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后布疼,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體摊趾,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年游两,在試婚紗的時候發(fā)現(xiàn)自己被綠了砾层。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,039評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡贱案,死狀恐怖肛炮,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情宝踪,我是刑警寧澤侨糟,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站瘩燥,受9級特大地震影響秕重,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜厉膀,卻給世界環(huán)境...
    茶點故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一溶耘、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧服鹅,春花似錦凳兵、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春聚蝶,著一層夾襖步出監(jiān)牢的瞬間杰妓,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工碘勉, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留巷挥,地道東北人。 一個月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓验靡,卻偏偏與公主長得像倍宾,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子胜嗓,可洞房花燭夜當晚...
    茶點故事閱讀 42,786評論 2 345

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

  • 1.ios高性能編程 (1).內(nèi)層 最小的內(nèi)層平均值和峰值(2).耗電量 高效的算法和數(shù)據(jù)結(jié)構(gòu)(3).初始化時...
    歐辰_OSR閱讀 29,320評論 8 265
  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴謹 對...
    cosWriter閱讀 11,089評論 1 32
  • iOS面試題目100道 1.線程和進程的區(qū)別高职。 進程是系統(tǒng)進行資源分配和調(diào)度的一個獨立單位,線程是進程的一個實體辞州,...
    有度YouDo閱讀 29,874評論 8 137
  • 今日體驗怔锌,今天不是很忙,晚上加班組裝組裝發(fā)動機变过,把自己沒有干過的東西練練手埃元,熟悉熟悉,下次干的時候就能自己動手了媚狰。
    任武科閱讀 188評論 0 0
  • 怎么破 糾紛掛劃上句號
    差異在閱讀 314評論 0 0