符合协议列表

NMu*_*nro 0 objective-c objective-c-protocol

我有一个条件,我希望视图控制器符合4种协议中的任何一种.

有没有办法检查它是否符合这4个协议中的任何一个而不在我的if中做一堆或语句?

你能制作一系列协议吗?

rob*_*off 5

当然,你可以制作一系列协议:

NSArray *protocols = @[@protocol(UIApplicationDelegate),
    @protocol(UIImagePickerControllerDelegate),
    @protocol(UIScrollViewDelegate),
    @protocol(NSFileManagerDelegate)];
Run Code Online (Sandbox Code Playgroud)

然后,您可以检查某个对象是否符合所有对象:

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

但是很难想象为什么你想在运行时这样做.

也许你真正想要的是声明某些东西符合几种协议.你也可以这样做,编译器会在编译时为你检查它.例如:

@property (nonatomic, strong) id<UIApplicationDelegate, UIImagePickerController,
    UIScrollViewDelegate, NSFileManagerDelegate> swissArmyKnife;
Run Code Online (Sandbox Code Playgroud)

如果您尝试为此属性分配内容,并且它不符合所有四个协议,则编译器将发出警告.

也许你所说的是你要验证一个对象是否符合至少一个协议,但它不必符合所有协议.在这种情况下,您必须在运行时检查.但这对我来说闻起来很糟糕.

如果要向对象发送消息,但是您不确定它是否理解该消息,则最好专门检查要发送的消息,而不是检查协议是否一致.

// 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);
}
Run Code Online (Sandbox Code Playgroud)