0

ビュー コントローラーを 4 つのプロトコルのいずれかに準拠させたいという条件があります。

if で大量の or ステートメントを実行せずに、これら 4 つのプロトコルのいずれかに準拠しているかどうかを確認する方法はありますか?

プロトコルの配列を作成できますか?

4

2 に答える 2

5

確かに、プロトコルの配列を作成できます。

NSArray *protocols = @[@protocol(UIApplicationDelegate),
    @protocol(UIImagePickerControllerDelegate),
    @protocol(UIScrollViewDelegate),
    @protocol(NSFileManagerDelegate)];

次に、一部のオブジェクトがそれらすべてに準拠していることを確認できます。

UIViewController *vc = ...;
for (Protocol *protocol in protocols) {
    if (![vc conformsToProtocol:protocol]) {
        NSLog(@"object doesn't conform to %@", protocol);
    }
}

ただし、実行時にこれを行う理由を想像するのは困難です。

おそらく、あなたが本当に望んでいるのは、何かが複数のプロトコルに準拠していることを宣言することです。あなたもそれを行うことができ、コンパイラはコンパイル時にそれをチェックします。例えば:

@property (nonatomic, strong) id<UIApplicationDelegate, UIImagePickerController,
    UIScrollViewDelegate, NSFileManagerDelegate> swissArmyKnife;

このプロパティに何かを割り当てようとして、それが 4 つのプロトコルすべてに準拠していない場合、コンパイラは警告を発行します。

おそらく、オブジェクトが少なくとも1 つのプロトコルに準拠していることを確認したいが、すべてのプロトコルに準拠している必要はないということです。その場合、実行時にチェックする必要があります。しかし、それは私には悪い設計のようなにおいがします。

オブジェクトにメッセージを送信したいが、オブジェクトがメッセージを理解できるかどうかわからない場合は、プロトコルの適合性を確認するのではなく、送信するメッセージを具体的に確認する方がよいでしょう。

// This is probably not such a good idea.
if ([object conformsToProtocol:@protocol(NSFileManagerDelegate)]) {
    return [object fileManager:myFileManager shouldRemoveItemAtURL:url];
} else {
   return arc4random_uniform(2);
}


// This is probably better.
if ([object respondsToSelector:@selector(fileManager:shouldRemoveItemAtURL:)]) {
    return [object fileManager:myFileManager shouldRemoveItemAtURL:url];
} else {
   return arc4random_uniform(2);
}
于 2012-11-26T20:09:16.413 に答える
1

もちろん。

id object = ...;
Protocol *protocols[] = {@protocol(Blah), @protocol(Foo), @protocol(Bar)};
for(unsigned i = 0; i < sizeof(protocols) / sizeof(Protocol *); ++i) {
   if([object conformsToProtocol:protocols[i]]) {
     //do something...
     break;
   }
}
于 2012-11-26T20:08:01.633 に答える