self
可以在一個類的方法作爲多晶型類實例中使用。
因此,類方法new
可以實現這樣的:
+ (id)new
{
return [[self alloc] init];
}
和將返回正確的類型對於被傳遞消息類實例:
前一個:
NSArray * a = [NSArray new]; // << a is an NSArray
ex b:
NSMutableArray * a = [NSMutableArray new]; // << a is an NSMutableArray
請參閱下面的註釋。
所以你真正要面對的是確保協議中只有實例方法,並且(類)自己的方法映射出採用協議中的實例方法。
就設計......好吧,我們只是說我不會這樣寫的。一個單身人士會更清楚,更正確,但我甚至不喜歡單身人士,所以我不會採取這樣的路線。
產生此警告是因爲類別實例(通過的內容)確實採用delegate
參數指定的@protocol
。 Class
實例不是該類的一個實例。協議聲明確實適用於該類的實例。例如,如果採用NSLocking
,編譯器是否希望您也爲協議中聲明的每個實例方法實現類方法?答:從來沒有。你正在處理的實施是國際海事組織是這種語言濫用的情況之一,但它恰好運作。
爲了闡明術語:
的 「Class
實例」 是self
在一個類的方法:
+ (void)foo { self; }
的 「類的實例」 是在實例方法self
:
- (void)foo { self; }
實際上,-[NSObject conformsToProtocol:]
是+[NSObject conformsToProtocol:]
和+[NSObject class]
只是返回self
所以執行時沒有錯誤。
我還不清楚,那麼,爲什麼我收到警告,如果代碼符合您描述的標準。
我描述的標準適用於執行,但它從語言的語義偏離 - 因此,編譯器對這個絕對正確的。
對於解決的問題:有沒有辦法告訴編譯器「我的類的實例符合協議」,因爲採用的聲明適用於類的實例。
你有兩個主要選擇:
乾淨的,正確的做法:使用類的一個實例和實施所定義的協議。
或類型轉換類實例的協議:
ID代表=(ID)自我; fbSession = [FBSession sessionForApplication:SHKFacebookKey getSessionProxy:SHKFacebookSessionProxyURL delegate:delegate];
如果選擇#2,它可以幫助定義協議的實例方法使用類的方法,比如:
+ (void)protocolMethod { /* do stuff */ }
- (void)protocolMethod { [self.class protocolMethod]; }
,這也將意味着你永遠不需要實例。這將有所幫助,因爲如果協議會改變,它會添加警告。遵循約定時,這些警告會觸發類方法。
爲了減少噪音,你也可以考慮建立一些方法將強制轉換降低到一個位置:
+ (id<SomeProtocol>)sharedSomeProtocolDelegate
{
return (id<SomeProtocol>)self;
}
- (id<SomeProtocol>)sharedSomeProtocolDelegate
{
return [[self class] sharedSomeProtocolDelegate];
}
那麼你可以這樣寫:
fbSession = [FBSession sessionForApplication:SHKFacebookKey
getSessionProxy:SHKFacebookSessionProxyURL
delegate:[self sharedSomeProtocolDelegate]];
(注意的實現這些類型實際上是類集羣,並且您將在調試器中看到不同的東西或者如果打印出來)
您的編輯已清除。順便說一句,該協議只包含實例方法,它們都不涉及接收方。我仍然不清楚,那麼,爲什麼我收到警告,如果代碼符合您描述的標準。 – Jim 2012-01-27 04:01:50
@Jim詳細添加 – justin 2012-01-27 06:21:14