2015-02-05 78 views
0

我真的很希望有人能回答這個問題。我認爲我絕對不是唯一一個對此感到困惑的人,我無法找到任何清楚解釋這個概念的東西。紅寶石代表從可可開發人員背景解釋

我對委託模式的理解來自於研究Cocoa框架。對我來說,可可的實施非常明確。但是我很難在Ruby中理解它(標準庫的Delegator,SimpleDelegatorActiveSupportDelegate)。這對我來說毫無意義。主要是因爲一個是類型安全的,另一個是鴨子類型。你已經可以看到我的觀點,但請允許我擴大......這裏是我的如何使用可可的委託模式總結:

我們的「成分」是:2類,AB和,這Cocoa是可用於委託的預定義方法集。

的模式的實現,基本上如下:

  1. A定義了一套方法委託給B
  2. B的委託被設置爲A

    =>B現在可以調用委託方法,像這樣:@delegate.send(a_delegated_method)

什麼我不綁在一起的是紅寶石採用鴨打字的事實,所以你可以發送任何方法調用任何對象,對吧?因此,使用我剛剛解釋的模式,只要2個對象處於同一個域中,您可以在A@b.send(:a_delegated_method)之間說,反之亦然,而在B@a.send(:another_delegated_method)

難道是在Ruby中委託的地方是委託方法被定義的地方嗎?意思是我們從A類別內發送到屬性@b@b(:delegated_method))a :delegated_methodA本身內定義的內容?

希望這不是太混亂。我自己很疑惑,爲什麼代表甚至存在鴨子打字的語言,以及Delegator,SimpleDelegatorActiveSupportDelegate之間有什麼區別。

+0

委託是_pattern_。它與打字工作無關。這兩件事不僅是正交的,它們完全沒有關係。 – matt 2015-02-05 19:33:10

+0

我知道這是一種模式,但我的問題更多地是關於在兩種不同的環境中實施模式的變化,如果這是有道理的。 – believesInSanta 2015-02-05 20:10:39

回答

1

我不清楚你是否瞭解代表團如何在可可中工作。的確,Cocoa中委託模式的常見變種涉及到一個協議,但這只是一種靜默編譯器的方式。

所以我們先來談談靜音編譯器。你不能發送woohoo消息對象在Objective-C,除非兩種情況之一是真實的:

  • 編譯器有理由相信,這種對象可能爲woohoo消息作出響應。

  • 編譯器暫停判斷。

現在,第一種方法通常被使用 - 這就是協議的用途。但情況並非總是如此。它曾經是該代表團主要依靠非正式協議。可可還有非正式的協議。這個想法是要麼這個方法是通過一個類別注入到NSObject中的,要麼你注意鍵入對象作爲id,這樣它就可以發送任何消息。

現在讓我們來談談動態。非正式協議不再使用的原因是引入了允許協議聲明可選成員的功能。但是仍然需要活力!我們可能會以某種方式滿足編譯器,但在運行時我們必須確保將特定消息發送到某個對象是安全的。您的應用程序代理可能會採用UIApplicationDelegate,但Cocoa不會將它發送給applicationDidBecomeActive:消息,除非您的應用程序代理類實現了applicationDidBecomeActive: - 如果確實如此,則會崩潰,而且這不會很好。

而且,如果你可以讓過去的編譯器,你可以在Objective-C甚至比這更動態地進行授權,如下解釋:

https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtForwarding.html

的想法是,我們正前方去在運行時並且無論如何都會向對象發送消息!如果消息到達對象A無法處理,它可以看到對象B是否處理它。如果是這樣,它將消息傳遞給對象B.因此,我們可能不會崩潰!我用這種方法在我的應用程序之一:

- (id)forwardingTargetForSelector:(SEL)aSelector { 
    if ([self.originalDataSource respondsToSelector: aSelector]) 
     return self.originalDataSource; 
    return [super forwardingTargetForSelector:aSelector]; 
} 

在該代碼中,我的意思是,如果有消息到達,我不能處理它,我應該嘗試把它發送到另一個對象,稱爲self.originalDataSource

如果您仔細考慮,那幾乎與Ruby代表團完全相同。我有一個幫助對象,並且我無法處理的消息被傳遞給它。

此模式的另一種常見用法是包裝可可集合時。你不能繼承子類,比如NSArray,因爲它是一個類集羣,所以正確的方法就是包裝它。然後,您只需將所有內容轉發給NSArray,然後將其作爲NSArray進行鴨式輸入!就你的方法而言,你看起來像一個NSArray。然後你介紹一些行爲上的差異,現在你將鴨子作爲定製的NSArray。

+0

當你提到Ruby代表團時,你指的是Rails的ActiveSupport#委託嗎?標準圖書館的委託人呢?爲什麼即使有這些消息發送?你是說它只是處理method_missing異常呢?我意識到4個問題重疊有點btw :) – believesInSanta 2015-02-05 20:07:16