2011-10-01 153 views
15

我有一個家庭作業問題讓我很困惑。以下是一個問題的簡要解釋。Objective C協議的使用

想象一下,您正在開發一個應用程序,用於存儲聯繫人 信息。地址簿可以包含許多實體類型,例如人 是,公司或其他任何有聯繫信息。

  • 現在不是明確地檢查每一個對象類型寫 協議,聲明瞭一個對象必須的行爲,併成功 出現在您的地址簿。

我的理解和回答這個問題的力度,

  1. 構建具有下@required標籤每種類型的聯繫人信息的常用方法的協議。和其他所有不同的聯繫方式(如傳真號碼與公司有關聯,但不包括人員...)在@optional之下。在運行時,您可以使用selector來檢查對象是否響應任何給定的方法。 疑問:但是,這又是間接顯式檢查對象類型,我是對嗎?

  2. 我的第二個想法是在java中使用類似abstract class的東西。這意味着從抽象類繼承的類實現了自己的抽象方法。作爲一個天真的iOS開發人員,我不知道如何實現這一點?我不確定這是否會解決我的問題。如果有人知道這一點,我希望得到啓發。


外部讀取迄今所做的,請讓我知道,如果我要找的答案是在這些環節之一。我會再讀一遍來理解和解決這個:)。謝謝。

  1. http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjectiveC/Chapters/ocProtocols.html#//apple_ref/doc/uid/TP30001163-CH15-TPXREF144

  2. http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjectiveC/Chapters/ocProtocols.html#//apple_ref/doc/uid/TP30001163-CH15-TPXREF146

  3. http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjectiveC/Chapters/ocProtocols.html#//apple_ref/doc/uid/TP30001163-CH15-TPXREF149

+5

問題作業問題的絕佳方式。 +1以下http://catb.org/esr/faqs/smart-questions.html – 0x8badf00d

+0

此鏈接清楚解釋協議概念http://www.tutorialspoint.com/ios/ios_delegates.htm –

回答

10

協議是相同的東西作爲一個Java接口。它只是定義了類應該支持哪些方法。下面是清楚地解釋它的頁面:http://www.otierney.net/objective-c.html#protocols

從本質上講,如果你想要確保一個類將有一個phoneNumber方法(訪問到phoneNumber屬性),你會做這樣的事情:

@protocol ContactProtocol 
-(void) phoneNumber; 
@end 

@interface Person: NSObject <ContactProtocol> { 
    ... 
} 

@interface Company: NSObject <ContactProtocol> { 
    ... 
} 

然後在編譯時(或爲xcode 4生活)它會告訴你,如果你忘記將phoneNumber方法添加到PersonCompany類。

+6

協議不一樣抽象類;它們與Java中的接口類似。當你從一個抽象類派生一個類時,你繼承了這兩個方法及其實現。通過一個接口,你只能得到聲明。 Obj-c協議也是如此 - 當你聲明一個類實現了一個協議時,你必須提供方法實現。 – Caleb

+0

你是對的。我正在考慮接口!我正在更新我的答案。 –

+0

到Otierney.net的鏈接目前停用。這裏有一個鏈接到谷歌的緩存,不知道它會工作多久。http://webcache.googleusercontent.com/search?q=cache:QbGm74kZa1wJ:www.otierney.net/objective-c.html+&cd=1&hl=zh-CN&ct=clnk&gl=us – kevins

4

但是,這又是間接顯式檢查對象類型,對嗎?

不,檢查行爲與檢查類型不同。您可以將-respondsToSelector:發送給任何對象,如果結果爲YES,則可以發送消息,而不管對象的類型。您也可以要求一個對象實現一個給定的協議,再次而不關心它的實際類型:

id<SomeProtocol> foo; // foo points to any type that implements SomeProtocol 

我的第二個想法是使用類似Java中抽象類。

這可以工作,但它顯然不是你的任務要求,對吧?它說「...寫一個協議......」

Objective-C沒有提供一種方法來明確地做出一個Java抽象類的抽象方法。你只需創建這個類,如果你不希望它直接實例化,那麼你可以在某個地方記錄它。

+0

此問題與Swift無關,但如果那麼,如果我錯了,請糾正我的錯誤:你的第一個答案是:是的,現在在Swift中,協議是一種類型,只是你委託?.someMethod而不是與respondsToSelector相同它將運行函數如果設置了委託......第二個問題:(在閱讀你接受的答案的評論之後)在Swift中,因爲你也可以像抽象類一樣爲協議提供默認實現。 – Honey

+1

@Honey這個答案早於Swift,應該在這種情況下閱讀。我的評論也一樣。即使問題與Swift同時出現,問題的標題清楚地表示爲「Objective-C」,問題被標記爲[tag:objective-c]。 – Caleb

+0

我真的知道這一點,我只是問起它與Swift的區別,這個主題有答案,我只是檢查是否能夠正確地將所有內容放在一起(尤其是與上面的註釋一起)。 – Honey

1

你有...選項。

可選的方法對於編寫類符合協議的人來說是很方便的,對於使用協議的人來說很煩。所以這取決於你想要取悅誰。

可選方法並不像檢查類型那麼糟糕。想象一下訪問可接觸實體對象時代碼的外觀。當你使用可選的方法時,你必須有一個if case和一個else case。這並不像前進一樣方便,並假設你可以調用該方法。但它比檢查類型更方便。對於每種不同類型的實體(以及其他情況,這可能是斷言),這將是一種情況。此外,如果使用可選方法,則有關該實體的信息將封裝在其類中。如果您在調用方法之前檢查類型,則有關實體提供的聯繫信息類型的信息在調用代碼中的類外部。如果您升級實體以提供其他類型的聯繫人,那麼在您更新呼叫代碼之前,此改進功能將不可用。

選項B是使所有需要的方法,但給他們的選項返回一個值,指示沒有信息可用,如無。當然,這仍然意味着如果要檢查一個零結果,它就不那麼冗長了。解決此問題的更好辦法是讓方法返回多個聯繫人的集合。畢竟,人們可以有多個電話號碼。然後爲了表明聯繫類型不適用,您只需返回一個空集合。

不足之處在於,誰寫符合協議的類的人必須添加一個簡單的存根方法,說return nil什麼的。