2012-04-06 179 views
15

NSObject協議附帶了股票協議模板,但它似乎並不是協議實際實現所需的全部。離開它似乎沒有任何改變。那麼,協議是否真的需要繼承它,還是隻是一個不必要的附加組件?必須協議符合NSObject協議?

回答

19

多年來,我(和很多喜歡我)沒有使我們的協議符合<NSObject>。它工作正常。但它通常很煩人。最常見的煩惱是你不能使用respondsToSelector:,而不會回到NSObject*(這種方式會破壞協議的全部要點)。這在ObjC1的日子裏並不重要,因爲沒有@optional,所以我們沒有人擔心它(因爲沒有@optional,那些日子我們沒有使用多少協議)。然後ObjC2帶來了精彩的可選方法,並突然respondsToSelector:重要。我們慢了一陣子,但最終我們開始發現,如果你的協議符合<NSObject>,生活就簡單多了。有趣的是,現在這已經進入了Xcode,讓每個人都可以更方便地完成任務。

但是不,你不必這樣做。在許多情況下,這並不重要。但沒有太多理由不這樣做,所以我推薦它。

+0

好的答案......但即使是你提到NSObject協議的煩惱也只會在id obj中發揮作用,因爲如果你用類引用對象,編譯器就會知道繼承......大概從NSObject開始... – 2014-10-11 21:52:04

6

不一定。委託只是一個輔助對象 - 唯一的要求是委託類放置它的那些要求。如果您想要正式確定給定代表的要求,請創建一個正式協議,即使用@protocol指令聲明協議。如果符合NSObject的協議是其中的一個要求,你可以讓你的協議採納:

@protocol MyDelegateProtocol <NSObject> 
//... 
@end 

這麼說,我看不出有任何理由去創造,這不是從NSObject的或者是NSProxy衍生的委託,並且這兩個類都已經符合NSObject協議。

+0

如果協議不符合NSObject,派生自NSObject的委託會中斷嗎? (換句話說,不符合一般導致委託方法不被調用)? – CodaFi 2012-04-06 23:10:27

+2

由於NSObject符合NSObject協議,從NSObject派生的任何類也符合NSObject協議。所以不,從NSObject派生的委託不會因爲它所採用的委託協議沒有明確採用NSObject協議而中斷。 – Caleb 2012-04-07 02:10:01

1

並非每個對象都必須繼承NSObject,所以我猜如果您期待這樣一個對象符合您的協議,則它不一定必須符合NSObject。

符合NSObject讓編譯器知道該對象符合基本要求 - 檢查出它NSObject Protocol Reference。不用說我遵從NSObject,編譯器如何知道我符合任何這一點?

NSObject被定義爲

@interface NSObject <NSObject> { 
    Class isa; 
} 

id被定義爲

typedef struct objc_object { 
    Class isa; 
} *id; 

所以對於id編譯器不知道它完全符合NSObject

1

推薦,而不是強制性的。

根據蘋果的官方文件ProgrammingWithObjectiveC.pdf

如果你嘗試,因爲它的定義同上,呼籲符合協議的ID 的respondsToSelector:方法,你會得到一個編譯器錯誤 沒有已知的實例方法。一旦你通過一個協議取得 一個id,所有靜止類型檢查都會返回;如果您嘗試調用任何未在 指定協議中定義的方法,您將得到 錯誤。避免編譯器錯誤的一種方法是將 自定義協議設置爲採用NSObject協議。

,因爲它的上面中定義的協議是不符合NSObject協議的協議。

作爲一個例子,它來定義協議,以符合 到NSObject的協議(一些NSObject的行爲是從 其類接口分成一個單獨的協議最好的做法; NSObject類 採用NSObject協議)。