你好,歡迎來到IOS教程網

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

iOS學習筆記之回調(一)

編輯:IOS編程技術

什麼是回調

看了好多關於回調的解釋的資料,一開始總覺得這個概念理解起來有點困難,可能是因為自己很少遇到這種類型的調用吧。探索良久之後,才算有點啟發,下面是自己的一點理解。
我們知道,在OSI網絡七層模型中,上層可以直接調用下層的代碼來為自己服務,這種調用是一種直接調用的方式。但是下層不能直接調用上層的代碼,除非上層為下層提供了相應的函數。如果上層為下層提供了相應的函數,那麼這個函數就被稱為回調函數,下層通過回調函數調用上層的這種方式就是一種“回調”。
我們假定下圖中的A代表應用層,B代表操作系統層,那麼下圖中的流程是:
step1:應用層A首先調用操作系統層B的代碼,然後假定應用層A在等待操作系統層B的某個資源,為了讓B在資源就位的時候可以通知A,A為B提供了一個函數(假定名為f)
step2:當A等待的資源就位時,B就可以調用函數f來通知A
在這個過程中,A設計了回調函數f,但實際調用回調函數的是B。事實上,A和B可以是同一個對象,為了便於理解和敘述,我們可以將兩個實體分開來看。

回調主要的應用場景是:當前運行的應用在等待某個特定的事件,如鼠標移動、觸摸事件等,當特定的事件發生後,需要通過某種方式告知正在等待的這個應用。

iOS中的回調

iOS中有三種方式可以實現回調
1、目標-動作
在應用等待前,要求當等待的特定事件發生時,向指定的對象發送某個特定的消息。接收消息的對象是目標,消息的選擇器是動作
2、輔助對象
在應用開始等待前,要求當等待的特定事件發生時,向遵守相應協議的輔助對象發送消息。委托對象數據源是常見的輔助對象。
3、通告
蘋果中有一種稱為通告中心的對象。在應用開始等待前,可告知通知中心,某個對象正在等待特定的消息。當應用等待的特定事件發生時,相關的對象會向通知中心發布通告,然後再由通知中心將通告轉發給正在等待該通告的對象。

目標-動作對

目標-動作是實現回調的一種較為簡單的方式。對上圖中的例子來講,目標就是接收消息的對象,就是在等待某個特定事件的那個對象,因此A是B的目標,而動作就是那個回調函數,因此是A設計的f函數。
選擇器
在繼續討論回調前,先簡單介紹一下選擇器。在iOS中,當某個對象收到消息時,會向該對象的類進行查詢,檢查是否有與消息名稱匹配的方法。該查詢過程會沿著繼承層次結構向上,直到在某個類中查詢到或到達繼承的頂層。在查詢過程中,要求查詢的速度非常快速。如果使用方法的實際名稱(可能會很長)進行查詢,那麼查詢速度會很慢。因此,編譯器會為每個其接觸過的方法附帶一個唯一的數字。在實際運行過程中,使用這個數字而不是方法名來查詢。這個唯一的數字就成為選擇器。通過編譯指令@selector,可以得到與方法名相對應的選擇器。
為了更加清晰的理解目標-動作對的機制,我們以一個簡單的案例來分析。在下面的案例中,我們創建一個擁有NSRunLoop對象和NSTimer對象的應用。每隔2秒,NSTimer對象會向其目標發送指定的動作消息。同時,創建一個類,該類的實例設置為NSTimer對象的目標,如下圖所示。

創建的代碼如下:
首先創建Logger類作為NSTimer類的目標,在頭文件中聲明一個sayOuch函數。
Logger.h

@interface Logger : NSObject- (void)sayOuch:(NSTimer *)t;@end

在.m文件中實現sayOuch方法,讓其在控制台輸出一句話,便於觀察方法運行結果。
Logger.m

@implementation Logger- (void)sayOuch:(NSTimer *)t{    NSLog(@"Ouch!");}@end

接下來在main函數中聲明兩個對象,分別是Logger類的對象logger,和NSTimer類的對象timer。我們把logger對象設置為timer對象的目標。
main

int main(int argc, const char * argv[]) {    @autoreleasepool {        // insert code here...        Logger *logger = [[Logger alloc] init];        NSTimer *timer = [NSTimer                          scheduledTimerWithTimeInterval:2.0                                                  target:logger                                                selector:@selector(sayOuch:)                                                userInfo:nil                                                 repeats:YES];                        [[NSRunLoop currentRunLoop] run];    }    return 0;}

上述代碼中,Logger類設置的函數sayOuch將被NSTimer對象調用,因此這個sayOuch函數就是一個回調函數。對照到A-B那個圖來說,這個案例中的NSTimer類是B,它位於下層,而Logger類是上層,它提供了回調函數給下層調用。

總結

在iOS編程中,目標-動作對這種回調方式對用於UI控制器和UI控件之間,這種機制產生的原因是,某些事件不能確定何時發生(例如某個按鈕被點擊),但是一旦發生之後,就要按照預先定義的回調函數去處理。

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