iOS訊息機制

來源:互聯網
上載者:User

標籤:

每個應用程式或多或少,都由一些松耦合的對象構成,這些對象彼此之間要想很好的完成任務,就需要進行訊息傳遞。

一下是所有可用的訊息傳遞機制:

Core Data managed object context是notification的寄件者,而擷取這些notification的主體則是接收者。一個滑塊(slider)是action訊息的寄件者,而在代碼裡面對應著實現這個action的responder就是接收者。對象中的某個屬性支援KVO,那麼誰修改這個值,誰就是寄件者,對應的觀察者(observer)則是接收者。

KVOKVO提供了這樣一種機制:當對象中的某個屬性值發生了改變,可以對這些值的觀察者做出通知。KVO的實現包含在Foundation裡面,基於Foundation構建的許多Framework對KVO都有所依賴。如果對某個對象中值的改變情況感興趣,那麼可以使用KVO訊息傳遞機制。這裡有兩個要求,首先,接收者(會接收到值發生改變的訊息)必須知道寄件者(值將發生改變的那個對象)。另外,接收者同樣還需要知道寄件者的生命週期,因為在銷毀寄件者對象之前,需要取消觀察者的註冊。如果這兩個要求都滿足了,訊息傳遞過程中可以是1對多(多個觀察者可以註冊某個對象中的值)。如果計劃在Core Data對象上使用KVO,需要知道這跟一般的KVO使用方法有點不同。那就是必須結合Core Data的故障機制(faulting mechanism),一旦core data出現了故障,它將會觸發其屬性對應的觀察者(即使這些屬性值沒有發生改變)。 Notification在不相關的兩部分代碼中要想進行訊息傳遞,通知(notifacation)是非常好的一種機制,它可以對訊息進行廣播。特別是想要傳遞豐富的資訊,並且不一定指望有誰對此訊息關心。通知可以用來發送任意的訊息,甚至包含一個userInfo字典,或者是NSNotifacation的一個子類。通知的獨特之處就在於寄件者和接收者雙方並不需要相互知道。這樣就可以在非常松耦合的模組間進行訊息的傳遞。記住,這種訊息傳遞機制是單向的,作為接收者是不可以回複訊息的。‘ delegation在蘋果的Framework中,delegation模式被廣泛的只用著。delegation允許我們定製某個對象的行為,並且可以收到某些確定的事件。為了使用delegation模式,訊息的寄件者需要知道訊息的接收者(delegate),反過來就不用了。這裡的寄件者和接收者是比較松耦合的,因為寄件者只知道它的delegate是遵循某個特定的協議。delegate協議可以定義任意的方法,因此你可以準確的定義出你所需要的類型。你可以用函數參數的形式來處理訊息內容,delegate還可以通過傳回值的形式給寄件者做出回應。如果只需要在相對接近的兩個模組之間進行訊息傳遞,那麼Delegation是一種非常靈活和直接方式。不過,過渡使用delegation也有一定的風險,如果兩個對象的耦合程度比較緊密,相互之間不能獨立存在,那麼此時就沒有必要使用delegate協議了,針對這種情況,對象之間可以知道相互間的類型,進而直接進行訊息傳遞。例如UICollectionViewLayout和NSURLSessionConfiguration。 blockBlock相對來說,是一種比較新的技術,它首次出現是在OS X 10.6和iOS 4中。一般情況下,block可以滿足用delegation實現的訊息傳遞機制。不過這兩種機制都有各自的需求和優勢。當不考慮使用block時,一般主要是考慮到block極易引起retain環。如果寄件者需要reatain block,而又不能確保這個引用什麼時候被nil,這樣就會發生潛在的retain環。假設我們想要實現一個table view,使用block替代delegate,來當做selection的回調,如self.myTableView.selectionHandler = ^void(NSIndexPath *selectIndexPath){}; 。這個代碼的問題在於self retain了table view,而table view為了之後能夠使用block,進而 retain了block。而table view又不能把這個引用nil掉,因為它不知道什麼時候不在需要這個block了。如果我們保證不了可以打破這個retain環,而我們又需要retain寄件者,此時block不是好的選擇。NSOperation就可以很好的使用block,因為它能再某個時機打破retain環:如:self.queue= [[NSOperationQueue alloca]init];myOperation *operation = [[myOperation alloca]init];operation.completionBlock = ^{[self finishedOperation];}; [self.queue addOperation:operation]; 。乍一看這似乎是一個retain環:self retain了queue,queue retain了operation,而operation retain了completion block,而completion blockretain了self。不過,在這裡,將operation添加到queue時,會使operation在某個時機被執行,然後從queue中remove掉(如果沒有被執行,就會有大問題了)。一單queue移除了operation之後,retain環就被打破了。再來一個樣本:這裡實現了一個視頻編碼器的類,裡面有一個名為encodeWithCompletionHandler:的方法。為了避免出現retain環,我們需要確保編碼器這個對象能夠在某個時機nil掉其對block的引用。其內部代碼如下所示: 
  1. @interface Encoder () 
  2. @property (nonatomic, copy) void (^completionHandler)(); 
  3. @end 
  4.  
  5. @implementation Encoder 
  6.  
  7. - (void)encodeWithCompletionHandler:(void (^)())handler 
  8.     self.completionHandler = handler; 
  9.     // do the asynchronous processing... 
  10.  
  11. // This one will be called once the job is done 
  12. - (void)finishedEncoding 
  13.     self.completionHandler(); 
  14.     self.completionHandler = nil; // <- Don‘t forget this! 
  15.  
  16. @end 
 在上面的代碼中,一旦編碼任務完成,就會調用complietion block,進而把引用nil掉。 如果我們發送的訊息屬於一次性的(具體到某個方法的調用),由於這樣可以打破潛在的retain環,那麼使用block是非常不錯的選擇。另外,如果為了讓代碼可讀性更強,更有連貫性,那最好是使用block了。根據這個思路,block經常可以用於completion handler、error handler等。  Target-ActionTarget-Action主要被用於響應使用者介面事件時所需要傳遞的訊息中。iOS中的UIControl和Mac中的NSControl/NSCell都支援這種機制。Target-Action在訊息的寄件者和接收者之間建立了一個非常鬆散耦合。訊息的接收者不知道寄件者,甚至訊息的寄件者不需要預Crowdsourced Security Testing道訊息的接收者。如果target是nil,action會在響應鏈(responder chain)中被傳遞,知道找到某個能夠響應該aciton的對象。在iOS中,每個控制項都能關聯多個target-action。基於target-action訊息傳遞的機制有一個局限就是發送的訊息不能攜帶自訂的payload。在Mac的action方法中,接收者總是被放在第一個參數中。而在iOS中,可以選擇性的將寄件者和和觸發action的事件作為參數。除此之外,沒有別的辦法可以對發送action訊息內容做控制。      
  • http://www.cnblogs.com/zylin/
   
      

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.