self
ポリモーフィック クラス インスタンスとしてクラス メソッドで使用できます。
したがって、クラス メソッドは次のnew
ように実装できます。
+ (id)new
{
return [[self alloc] init];
}
メッセージが送信された Class インスタンスの正しい型を返します。
例:
NSArray * a = [NSArray new]; // << a is an NSArray
例 b:
NSMutableArray * a = [NSMutableArray new]; // << a is an NSMutableArray
以下の注を参照してください。
したがって、実際に直面しているのは、プロトコルにインスタンス メソッドのみが存在すること、および (クラス) 自己のメソッドがプロトコルのインスタンス メソッドを採用するようにマップすることです。
設計に関しては... まあ、私はこのように書かなかったとだけ言っておきましょう. シングルトンの方がより明確で正確だったでしょうが、私はシングルトンが好きではないので、そのルートをたどりませんでした。
Classインスタンス (渡されるもの) がパラメーターで@protocol
指定されたを採用するため、警告が生成されdelegate
ます。Class
インスタンスはクラスのインスタンスではありません。プロトコル宣言は、クラスのインスタンスに実際に適用されます。たとえば、 を採用NSLocking
した場合、コンパイラは、プロトコルで宣言されたすべてのインスタンス メソッドに対してクラス メソッドも実装することを期待しますか? 答え: ありません。あなたが扱っている実装は、言語の誤用であるIMOの1つですが、たまたま機能します。
用語を明確にするには:
「Class
インスタンス」はself
クラスメソッドにあります:
+ (void)foo { self; }
「クラスのインスタンス」はself
インスタンス メソッドにあります。
- (void)foo { self; }
実際に-[NSObject conformsToProtocol:]
は is+[NSObject conformsToProtocol:]
と+[NSObject class]
just が返さself
れるため、実行時にエラーは発生しません。
コードがあなたが説明した基準を満たしている場合、なぜ警告が表示されるのかはまだわかりません。
私が説明した基準は実行に適用されますが、言語のセマンティクスから逸脱しています。したがって、コンパイラはこれについて完全に正しいです。
問題の解決策:採用宣言はclass のインスタンスに適用されるため、コンパイラに「My Class instance conforms to protocol 」と伝える方法はありません。
主なオプションは 2 つあります。
クリーンで正しいアプローチ: クラスのインスタンスを使用し、プロトコルを定義どおりに実装します。
または、クラス インスタンスをプロトコルに型キャストします。
id デリゲート = (id)self; fbSession = [FBSession sessionForApplication:SHKFacebookKey getSessionProxy:SHKFacebookSessionProxyURL delegate:delegate];
#2 を選択した場合は、次のように、クラス メソッドを使用するようにプロトコルのインスタンス メソッドを定義すると役立つ場合があります。
+ (void)protocolMethod { /* do stuff */ }
- (void)protocolMethod { [self.class protocolMethod]; }
これは、インスタンスがまったく必要ないことも意味します。プロトコルが変更された場合に警告が追加されるため、役立ちます。規則に従うと、これらの警告がクラス メソッドにバブルアップします。
ノイズを減らすために、型キャストを 1 つの場所に減らすメソッドを作成することも検討してください。
+ (id<SomeProtocol>)sharedSomeProtocolDelegate
{
return (id<SomeProtocol>)self;
}
- (id<SomeProtocol>)sharedSomeProtocolDelegate
{
return [[self class] sharedSomeProtocolDelegate];
}
次に、次のように書くことができます。
fbSession = [FBSession sessionForApplication:SHKFacebookKey
getSessionProxy:SHKFacebookSessionProxyURL
delegate:[self sharedSomeProtocolDelegate]];
(これらの型の実装は実際にはクラス クラスターであり、デバッガーで、または出力された場合に何か異なることが表示されることに注意してください)