我有一个条件,我希望视图控制器符合 4 个协议中的任何一个。
有没有办法检查它是否符合这 4 个协议中的任何一个,而无需在我的 if 中执行一堆 or 语句?
你能制作一系列协议吗?
我有一个条件,我希望视图控制器符合 4 个协议中的任何一个。
有没有办法检查它是否符合这 4 个协议中的任何一个,而无需在我的 if 中执行一堆 or 语句?
你能制作一系列协议吗?
当然,您可以制作一系列协议:
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;
如果你试图给这个属性赋值,但它不符合所有四种协议,编译器会发出警告。
也许您所说的是您想验证一个对象是否符合至少一个协议,但它不必符合所有协议。在这种情况下,您必须在运行时进行检查。但这对我来说是个糟糕的设计。
如果您想向对象发送消息,但不确定它是否能理解该消息,最好专门检查您要发送的消息,而不是检查协议一致性。
// 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);
}
当然。
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;
}
}