「フォーマル」を強制しようとして@protocol
いますが、クラス/インスタンスがプロトコルの「必要な」メソッドを実際に実装しているかどうか、またはプロトコルに準拠していることを単に「宣言」しているかどうかについて、クラス/インスタンスを確実にテストできません。
私の困惑の完全な例…
#import <Foundation/Foundation.h>
@protocol RequiredProtocol
@required
- (NSString*) mustImplement; @end
@interface Cog : NSObject <RequiredProtocol> @end
@implementation Cog @end
@interface Sprocket : NSObject @end
@implementation Sprocket
- (NSString*) mustImplement
{ return @"I conform, but ObjC doesn't care!"; } @end
int main(int argc, char *argv[]) {
Protocol *required = @protocol(RequiredProtocol);
SEL requiredSEL = @selector(mustImplement);
void (^testProtocolConformance)(NSObject*) = ^(NSObject *x){
NSLog(@"Protocol:%@\n"
"Does %@ class conform:%@ \n"
"Do instances conform:%@ \n"
"Required method's result:\"%@\"",
NSStringFromProtocol ( required ),
NSStringFromClass ( x.class ),
[x.class conformsToProtocol:required] ? @"YES" : @"NO",
[x conformsToProtocol:required] ? @"YES" : @"NO",
[x respondsToSelector:requiredSEL] ? [x mustImplement]
: nil );
};
testProtocolConformance ( Cog.new );
testProtocolConformance ( Sprocket.new );
}
結果:
Protocol:RequiredProtocol
Does Cog class conform:YES
Do instances conform:YES
Required method's result:"(null)"
Protocol:RequiredProtocol
Does Sprocket class conform:NO
Do instances conform:NO
Required method's result:"I conform, but ObjC doesn't care!"
@protocol
のメソッド ( ) を実装するクラスとそのインスタンスが にSprocket
戻るのNO
はconformsToProtocol
なぜですか?
そして、実際には準拠していないのに、準拠していると言っているものが ( Cog
) を返すのはYES
なぜですか?
適合性を装うために必要なのは宣言だけである場合、正式なプロトコルのポイントは何ですか?
@selector
複数の を呼び出すことなく、複数の の完全な実装を実際に確認するにはどうすればよいですrespondsToSelector
か?
@Josh Caswell .. diff
2 つを ing せずに.. あなたの応答は、NSObject
私がその間に使用していたカテゴリと同様の効果を達成すると思います…</p>
@implementation NSObject (ProtocolConformance)
- (BOOL) implementsProtocol:(id)nameOrProtocol {
Protocol *p = [nameOrProtocol isKindOfClass:NSString.class]
? NSProtocolFromString(nameOrProtocol)
: nameOrProtocol; // Arg is string OR protocol
Class klass = self.class;
unsigned int outCount = 0;
struct objc_method_description *methods = NULL;
methods = protocol_copyMethodDescriptionList( p, YES, YES, &outCount);
for (unsigned int i = 0; i < outCount; ++i) {
SEL selector = methods[i].name;
if (![klass instancesRespondToSelector: selector]) {
if (methods) free(methods); methods = NULL; return NO;
}
}
if (methods) free(methods); methods = NULL; return YES;
}
@end