iOS學習筆記之回調(二)

來源:互聯網
上載者:User

標籤:

寫在前面

上一篇學習筆記中簡單介紹了通過目標-動作對實現回調操作:建立兩個對象timer和logger,將logger設定為timer的目標,timer定時調用logger的sayOuch函數。在這個例子中,timer的任務比較簡單,只完成一項任務:在指定的時刻觸發事件。在這種情況下,適合選擇目標-動作來實現回調,但這種方式不適合要發送多個回調的情況。

輔助對象

輔助對象是另一種實現回調的方式。在應用開始等待前,要求當等待的特定事件發生時,向遵守相應協議的輔助對象發送訊息。委派物件資料來源是常見的輔助對象。

案例

假定我們建立一個NSURLConnection對象並從一個給定的url中擷取資料,然後等待回調。回呼函數被觸發的時機包括:獲得資料、資料擷取完成、擷取資料失敗等。
可見,如果只是簡單的目標-動作隊機制,無法實現這些複雜的回調。因此,我們為NSURLConnection對象設定一個輔助對象,這個輔助對象專門負責處理特定事件發生之後的事情,也就是說,當特定的事件發生後,NSURLConnection對象會向輔助對象發送訊息。這些訊息包含在一套協議中。協議和介面概念有些相似,協議就是一組方法的聲明,遵循相應協議的類必須實現協議中的方法(可以只實現部分方法)。
我們假定讓Logger類型的對象成為NSURLConnection對象的輔助對象,也就是說,將Logger對象賦給NSURLConne對象的成員變數delegate。Logger類必須實現NSURLConnection協議中的部分活全部方法。關係圖如下:

首先更改Logger類的代碼,由於要接收資料,因此為Logger類添加一個NSMutableData類型的屬性,如下:
Logger.h

@property NSMutableData *incomingData;

然後在Logger.m中實現協議中的部分方法

//收到一定位元組數的資料後會被調用- (void)connection:(NSURLConnection *)connection    didReceiveData:(NSData *)data{    NSLog(@"received %lu bytes", [data length]);        if (!self.incomingData) {        self.incomingData = [[NSMutableData alloc] init];    }        [self.incomingData appendData: data];}//最後一部分資料處理完畢後,會被調用- (void)connectionDidFinishLoading:(NSURLConnection *)connection{    NSLog(@"Got it all!");        NSString *string = [[NSString alloc] initWithData:self.incomingData                                             encoding:NSUTF8StringEncoding];    self.incomingData = nil;    NSLog(@"string has %lu characters", [string length]);        NSLog(@"The whole string is %@", string);}//擷取資料失敗時,會被調用- (void)connection:(NSURLConnection *)connection  didFailWithError:(NSError *)error{    NSLog(@"connection failed: %@",[error localizedDescription]);    self.incomingData = nil;}

在main函數中建立Logger對象和NSURLConnection,並將前者設定為後者的輔助對象:

Logger *logger = [[Logger alloc] init];                NSURL *url = [NSURL URLWithString:@"http://www.cnblogs.com/scut-linmaojiang/p/iOS-huidiao-y.html"];                NSURLRequest *request = [NSURLRequest requestWithURL:url];        NSURLConnection *fetchConn = [[NSURLConnection alloc]                                               initWithRequest:request                                                      delegate:logger                                              startImmediately:YES];

如上所示,當NSURLConnection對象fetchConn從指定url擷取資料時,將logger對象設定為它的輔助對象,也就是將logger作為fetchConn對象的委託。fetchCon擷取資料過程中的各種狀態會觸發logger執行對應狀態下的方法。利用斷點設定,我們可以知道正常情況下,logger執行回呼函數的順序為:
1、接收到資料,執行

- (void)connection:(NSURLConnection *)connection    didReceiveData:(NSData *)data

運行如下:

2、最後一部分資料處理完畢,執行

- (void)connectionDidFinishLoading:(NSURLConnection *)connection

運行如下:

...

url是上一篇筆記的地址,擷取到的資料是以html格式顯示的

如果電腦處理斷網狀態,那麼fetchConn將無法擷取到資料,此時logger將執行下面的回呼函數

- (void)connection:(NSURLConnection *)connection  didFailWithError:(NSError *)error

運行如下:

總結

對比目標-動作對機制和輔助對象機制這兩種實現回調的方式可知,當某個對象只提供了一個回呼函數時,使用目標-動作對較為合適。而當某個對象要提供多個回呼函數,也就說要接收多個回調資訊時,使用遵循相應協議的輔助對象較為合理。

iOS學習筆記之回調(二)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.