你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS編程技術 >> iOS學習筆記之回調(二)

iOS學習筆記之回調(二)

編輯:IOS編程技術

寫在前面

上一篇學習筆記中簡單介紹了通過目標-動作對實現回調操作:創建兩個對象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

運行截圖如下:

總結

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

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved